Поведение EventWaitHandle для pthread_cond_t
-
02-07-2019 - |
Вопрос
Недавно я увидел свет мощного поведения EventWaitHandle в C # и решил перенести некоторые функции в дочернее приложение, чтобы сделать то же самое.Единственная проблема заключается в том, что дочернее приложение написано на C.
Ничего особенного, я использую pthreads, у которых есть тип данных pthread_cond_t, который позволяет передавать сигналы.Мой единственный вопрос заключается в том, возможно ли, чтобы cond был "сигнализирован" до того, как на нем что-то будет ожидаться?
Прямо сейчас мой тест говорит "нет".То есть, если ThreadA подает сигнал до того, как ThreadB ожидает, ThreadB будет ждать неопределенно долго.Есть ли другой тип pthread, который я могу использовать, который ведет себя ближе к функциональности EventWaitHandle в C #?Объект получает сигнал, что означает, что первый поток, ожидающий его, немедленно передаст его и установит для него значение unsignled.
Обернуть pthread_cond в другую структуру данных было бы не слишком сложно для достижения этой цели.Но опять же, доступна ли эта функциональность уже в библиотеке pthread?
Решение
Если вы правильно используете условные переменные, это не будет иметь значения.
Основной поток вашего кода должен быть (в псевдокоде):
lock(lockobj);
while (!signalled) {
wait(condvar);
}
signalled = false;
unlock(lockobj);
на стороне ожидания, и:
lock(lockobj);
signalled = true;
notify(condvar);
unlock(lockobj);
на стороне сигнализации.(Конечно, используемые объект блокировки и переменная условия должны быть одинаковыми с обеих сторон.) Надеюсь, это поможет!
Другие советы
Альтернативный ответ (также в псевдокоде), если вы хотите множественные сигналы (т.е., если сигнал подан дважды, то два потока могут ждать, прежде чем состояние снова будет отменено).
Ожидающая сторона:
lock(lockobj);
while (signalled != 0) {
wait(condvar);
}
--signalled;
unlock(lockobj);
Сигнальная сторона:
lock(lockobj);
++signalled;
notify(condvar);
unlock(lockobj);
В итоге я просто заключил тип условия в новую структуру и создал несколько простых функций, которые ведут себя очень похоже на EventWaitHandle из C #.Мне нужны были два мьютекса, чтобы получить надлежащий сериализованный доступ.
Параметр cond_mutex используется для ожидания условной переменной, в то время как параметр data_mutex используется при установке состояния с signaled на not signaled.
Режим сброса тот же, что и в C #.АВТОМАТИЧЕСКИЙ или РУЧНОЙ.Это позволяет event_wait_t автоматически сбрасывать себя после ожидания.Или позволить программисту вручную сделать это с помощью вызова event_wait_reset(event_wait_t * ewh);