Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 [ 63 ] 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

Функция pthread rwlock tryrdlock

в листинге 8.5 показана наша реализация функции pthread rwlock tryrdlock, которая не вызывает приостановления вызвавшего ее потока.

Листинг 8.5. Функция pthread rwlock tryrdlock: попытка заблокировать ресурс для чтения

my rwlock/pth read rwlock tryrdl ock.с

1 linclude unpipc.h

2 linclude pthread rwlock.h

3 int

4 pthread rwlock tryrdlock(pthread rwlock t *rw)

6 int result:

7 if (rw->rw magic != RW MAGIC)

8 return(EINVAL):

9 if ( (result = pthread mutexJock(&rw->rw mutex)) != 0)

10 return(result):

11 if (rw->rw refcount < 0 rw->rw nwaitwriters > 0)

12 result = EBUSY: /* блокировка установлена пишущим потоком или

есть пишущие потоки, ожидающие освобождения ресурса */

13 else

14 rw->rw refcount++: /* увеличение количества блокировок на чтение */

15 pthread mutex unlock(&rw->rw mutex):

16 return(result):

17 }

11-14 Если блокировка в данный момент установлена на запись или есть процессы, ожидающие возможности установить ее на запись, возвращается ошибка с кодом EBUSY. В противном случае мы устанавливаем блокировку, увеличивая значение счетчика rw refcount.

Функция pthread rwlock wrlock

Текст функции pthread rwlock wrlock приведен в листинге 8,6. 11-17 Если ресурс заблокирован на считывание или запись (значение rw refcount отлично от 0), мы приостанавливаем выполнение потока. Для этого мы увеличиваем rw nwaitwriters и вызываем pthread cond wait с условной переменной rw condwriters. Для этой переменной посылается сигнал при снятии блокировки чтения-записи, если имеются ожидающие разрешения на запись процессы.

18-19 После получения блокировки на запись мы устанавливаем значение rw ref count в-1.

Функция pthread rwlock trywrlock

Неблокируемая функция pthread rwlock trywrlock показана в листинге 8.7. 11-14 Если значение счетчика rw refcount отлично от нуля, блокировка в данный момент уже установлена считывающим или записывающим процессом (это без-



различно) и мы возвращаем ошибку с кодом EBUSY. В противном случае мы устанавливаем блокировку на запись, присвоив переменной rw refcount значение -1.

Листинг 8.6. Функция pthread rwlock wrlock: получение блокировки на запись

my rwlock/pth read rwlock wrlock.с

1 linclude unpipc.h

2 linclude pthread rwlock.h

3 int

4 pthread rwlock wrlock(pthread rwlock t *rw)

6 int result;

7 if (rw->rw magic != RW MAGIC)

8 return(EINVAL);

9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0)

10 return(result);

11 while (rw->rw refcount != 0) {

12 rw->rw nwaitwriters++;

13 result = pthread cond wait(&rw->rw condwriters. &rw->rw mutex):

14 rw->rw nwaitwriters--:

15 if (result != 0)

16 break:

17 }

18 if (result == 0)

19 rw->rw refcount = -1;

20 pthread mutex unlock(&rw->rw mutex);

21 return(result);

22 }

Листинг 8.7. Функция pthread rwlock trywrlock: попытка получения блокировки на запись

my rwlock/pthread rwlock trywrlock.с

1 linclude unpipc.h

2 linclude pthread rwlock.h

3 int

4 pthread rwlock trywrlock(pthread rwlock t *rw)

6 int result;

7 if (rw->rw magic != RW MAGIC)

8 return(EINVAL);

9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0)

10 return(result);

11 if (rw->rw refcount != 0)

12 result = EBUSY; /* заблокирован пишущим потоком или ожидающим

возможности записи */

13 else



Листинг 8.7 (продолжение)

14 rw->rw refcount = -1; /* доступна */

15 pthread mutex unlock(&rw->rw mutex);

16 return(result);

17 }

Функция pthread rwlock unlock

Последняя функция, pthread rwlock unlock, приведена в листинге 8.8.

Листинг 8.8. Функция pthread rwlock unlock: разблокирование ресурса

my rwlock/pthread rwlock unl ock.с

1 #include unpipc.h

2 linclude pthread rwlock.h

3 int

4 pthread rwlock unlock(pthread rwlock t *rw)

6 int result:

7 if (rw->rw magic != RW MAGIC)

8 return(EINVAL):

9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0)

10 return(result):

11 if (rw->rw refcount > 0)

12 rw->rw refcount--: /* снятие блокировки на чтение */

13 else if (rw->rw refcount == -1)

14 rw->rw refcount = 0: /* снятие блокировки на запись */

15 else

16 err dump( rw refcount = *d . rw->rw refcount);

17 /* преимущество отдается ожидающим возможности записи потокам */

18 if (rw->rw nwaitwriters > 0) {

19 if (rw->rw refcount == 0)

20 result = pthread cond signal(&rw->rw condwriters):

21 } else if (rw->rw nwa.itreaders > 0)

22 result = pthread cond broadcast(&rw->rw condreaders):

23 pthread mutex unlock(&rw->rw mutex):

24 return(result):

25 }

11-16 Если rwrefcount больше 0, считывающий поток снимает блокировку на чтение. Если rwref count равно -1, записывающий поток снимает блокировку на запись.

17-22 Если имеются ожидающие разрешения на запись потоки, по условной переменной rwcondwri ters передается сигнал (если блокировка свободна, то есть значение счетчика rwrefcount равно 0). Мы знаем, что только один поток может осуществлять запись, поэтому используем функцию pthread cond signal. Если нет потоков, ожидающих возможности записи, но есть потоки, ожидающие возможности чтения, мы вызываем pthread cond broadcast для переменной rw condreaders, поскольку возможно одновременное считывание несколькими потоками. Обра-



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 [ 63 ] 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.