Чтение онлайн

ЖАНРЫ

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:
Листинг 10.31. Функция sem_unlink

//my_pxsem_mmap/sem_unlink.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_unlink(const char *pathname)

5 {

6 if (unlink(pathname) == –1)

7 return(-1);

8 return(0);

9 }

Функция sem_post

В

листинге 10.32 приведен текст функции sem_post, которая увеличивает значение семафора, возобновляя выполнение всех процессов, заблокированных в ожидании этого события.

Листинг 10.32. Функция sem_post

//my_pxsem_mmap/sem_post.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_post(mysem_t *sem)

5 {

6 int n;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 if ((n = pthread_mutex_lock(&sem->sem_mutex)) != 0) {

12 errno = n;

13 return(-1);

14 }

15 if (sem->sem_count == 0)

16 pthread_cond_signal(&sem->sem_cond);

17 sem->sem_count++;

18 pthread_mutex_unlock(&sem->sem_mutex);

19 return(0);

20 }

11-18 Прежде чем работать со структурой, нужно заблокировать соответствующее взаимное исключение. Если значение семафора изменяется с 0 на 1, нужно вызвать pthread_cond_signal, чтобы возобновилось выполнение одного из процессов, зарегистрированных на уведомление по данной условной переменной.

Функция sem_wait

В листинге 10.33 приведен текст функции sem_wait, которая ожидает изменения значения семафора с 0 на положительное, после чего уменьшает его на 1.

Листинг 10.33. Функция sem_wait

//my_pxsem_mmap/sem_wait.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_wait(mysem_t *sem)

5 {

6 int n;

7 if (setn->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 if ((n = pthread_mutex_lock(&sem->sem_mutex)) != 0) {

12 errno = n;

13 return(-1);

14 }

15 while (sem->sem_count == 0)

16 pthread_cond_wait(&sem->sem_cond, &sem->sem_mutex);

17 sem->sem_count--;

18 pthread_mutex_unlock(&sem->sem_mutex);

19 return(0);

20 }

11-18

Прежде чем работать с семафором, нужно заблокировать соответствующее взаимное исключение. Если значение семафора 0, выполнение процесса приостанавливается в вызове pthread_cond_wait до тех пор, пока другой процесс не вызовет pthread_cond_signal для этого семафора, изменив его значение с 0 на 1. После того как значение становится ненулевым, мы уменьшаем его на 1 и разблокируем взаимное исключение.

Функция sem_trywait

В листинге 10.34 приведен текст функции sem_trywait, которая представляет собой просто неблокируемый вариант функции sem_wait.

11-22 Мы блокируем взаимное исключение и проверяем значение семафора. Если оно положительно, мы вычитаем из него 1 и возвращаем вызвавшему процессу код 0. В противном случае возвращается –1, а переменной errno присваивается код ошибки EAGAIN.

Листинг 10.34. Функция sem_trywait

//my_pxsem_nmap/sem_trywait.с

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_trywait(mysem_t *sem)

5 {

6 int n, rc;

7 if (sem->sem_magic != SEM_MAGIC) {

8 errno = EINVAL;

9 return(-1);

10 }

11 if ((n = pthread_mutex_lock(&sem->sem_mutex)) != 0) {

12 errno = n;

13 return(-1);

14 }

15 if (sem->sem_count > 0) {

16 sem->sem_count--;

17 rc = 0;

18 } else {

19 rc = –1;

20 errno = EAGAIN;

21 }

22 pthread_mutex_unlock(&sem->sem_mutex);

23 return(rc);

24 }

Функция sem_getvalue

В листинге 10.35 приведен текст последней функции в этой реализации — sem_getvalue. Она возвращает текущее значение семафора.

11-16 Мы блокируем соответствующее взаимное исключение и считываем значение семафора.

Листинг 10.35. Функция sem_getvalue

//my_pxsem_mmap/sem_getvalue.c

1 #include "unpipc.h"

2 #include "semaphore.h"

3 int

4 mysem_getvalue(mysem_t *sem, int *pvalue)

Поделиться с друзьями: