>Уважаемый sas! Вы писали:
>> Т.к. condition variable ( даже одна
>>из ее частей) по природе может изменяться в разных потоках, то
>>мьютекс должен быть один и тот же. Если у Вас 2
>>или больше condition variables и они никак не пересекаются, то можно
>>и нужно использовать разные мьютексы (по одному на каждую из condition
>>variables).
>>
>>Кстати всегда лучше поcылать сигнал ВНЕ мьютекса:
>> pthread_mutex_lock(&mutex);
>> ...
>> pthread_mutex_ulock(&mutex);
>> pthread_cond_signal(&condVar);
>>
>>Это надо потому, что больше шансов, что после сигнала другой поток получит
>>мьютекс для блокировки.
>Ведь вызов pthread_cond_signal(&condVar); может быть потенциально опасен (напр. произошло переключение контекста и
>другой поток вызывает pthread_cond_wait(...))Или при вызове не изменяются поля структуры pthread_cond_t?
>Или эти операции атомарны?
"pthread_cond_signal - unblock a thread waiting for a condition variable" Кстати на многих системах проснуться могут больше чем один поток
Единственное что может произойти - это поток проснулся, не смог взять контроль и заснул опять.
pthread_cond_t - системно/библиотеко зависимый тип объекта Он может быть указателем или структурой или ... То как он изменяется/используется определяется системой/библиотекой К этому объекту применяются те же правила что и к остальным разделяемым данным (см первый пост) Механизм обеспечения этого - "implementation specific"
Исторически, из-за ошибки в документации к Solaris меньше 2.6, считалось что
pthread_cond_signal должен вызываться изнутри залокированного мьютекса (lost wakeup проблема) На самом деле это не так Кстати я так и не смотрел документацию к Solaris 2.6 или старше чтобы проверить исправлена ли ошибка :)
>
>>Ксатати на Windows существует уже упомянутые Event Semaphore objects, которые используются для
>>тех же целей, что и condition variables (CreateEvent,OpenEvent, SetEvent, ResetEvent, PulseEvent,
>>WaitForSingleObject, WaitForMultipleObjects ).
>
>Но ведь это не тоже самое, что condition variables (которые всегда используются
>вместе с мьютексом и операция отпускание_мьютекса-засыпание_на_condVar выполняется атомарно). И если на
>платформе NT с этим еще можно как-то бороться (с пом. SignalObjectAndWait(...)
>) то что делать на 95/98 вообще говоря не совсем ясно.
>:(
На самом деле "событийные объекты" (Event Objects) - можно рассматривать как "синонимы" condition variables:
/*** Поток 1 ***/
/* Заснули (nonsignaled state) пока другой поток не вызовет PulseEvent() (wakeup problem) или SetEvent() */
WaitForSingleObject( my_mutex );
while ( condition == FALSE ) {
/* Блокируем "событие" занято*/
ResetEvent( event );
/* другие могут использовать мьютекс */
ReleaseMutex( my_mutex );
/*наш код*/
/* lost wakeup problem!!! */
WaitForSingleObject( event );
WaitForSingleObject( my_mutex );
}
/*** поток 2 ***/
WaitForSingleObject( my_mutex );
condition = TRUE;
ReleaseMutex( my_mutex );
SetEvent( event );
К сожалению я давно под Windows не пишу и поэтому
1 Это только скелет кода
2 по поводу 95/98 вообще ничего не помню :(
Успехов
--- sas