C ++ Win / Linux событие синхронизации потоков - PullRequest
0 голосов
/ 10 мая 2010

Здравствуйте, у меня есть некоторый кроссплатформенный код с помощью unsing #ifdef OS,

У меня есть очередь, защищенная CriticalSection в Windows и pthread_mutex_t в Linux.

Я хотел бы реализовать вызов Wait (timeout), который бы блокировал поток, пока что-то не было помещено в очередь. Я думал об использовании WaitForSingleObject в Windows, но, похоже, он не поддерживает CriticalSection. Какие Win32 и какие функции Linux я должен использовать для Ожидания и Сигнала для возникновения условия.

Спасибо

Ответы [ 5 ]

1 голос
/ 10 мая 2010

Я думаю, что условия повышения могут быть тем, что вам нужно. Он кроссплатформенный, поэтому вам не придется беспокоиться о разных реализациях в зависимости от ОС.

Другая альтернатива - использовать Windows Events с WaitForSingleObject() и совершенно новый linux eventfd() с select() или poll().

0 голосов
/ 10 мая 2010

С pthread, условной переменной.

В Windows похоже, что вам нужен семафор. Семафоры Win32 имеют счетчик, который начинается с нуля - в этот момент дескриптор не сигнализируется. Когда вы добавляете элементы в очередь, вы увеличиваете счетчик семафоров с ReleaseSemaphore - Каждый счетчик, добавленный к семафору, будет удовлетворять один вызов функции WaitforXXXObject, поэтому, если вы добавили 3 элемента в очередь, вы ReleaseSemaphore со счетом 3. WaitFor ... будет возвращаться 3 раза, прежде чем дескриптор снова не будет сигнализирован.

0 голосов
/ 10 мая 2010

Кажется, я искал переменную условия.

На окнах Они работают с критическим значением Section и SleepConditionVariableCS

В Linux pthread_cond_timedwait работает с pthread.

Спасибо всем.

0 голосов
/ 10 мая 2010

Вы можете (вроде) имитировать попытку с тайм-аутом, используя TryEnterCriticalSection, но по большей части, если вы хотите тайм-аут, вам может быть лучше использовать mutex вместо этого (когда вы приступите к этому критическая секция - это, в основном, обертка вокруг мьютекса).

Другой возможностью было бы использование библиотеки Win32 pthreads , которая, вероятно, позволит компилировать ваш код Linux под Win32 без изменений (и вы просто удалите свой собственный код Win32).

Это очень похоже на поддержку потоков, которая была добавлена ​​в библиотеку C ++ 0x, хотя она не (даже не пытается) точно следовать новому стандарту. Если вы хотите следовать стандарту, вы можете использовать библиотеку Энтони Уильямса Just Thread (предупреждение: по разумной цене, но не в любом смысле бесплатно).

Редактировать (в ответ на вопросы Билли О'Нила): Если подумать об этом, на самом деле - это легко доступный исходный код , который показывает большую часть происходящего. Структура данных CRITICAL_SECTION определена в winbase.h как определение типа RTL_CRITICAL_SECTION. Это, в свою очередь, определяется в WinNT.h как:

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //

    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

Если память служит, основная идея о том, как это используется, работает примерно так:

  1. Если этот поток уже владеет критической секцией, увеличьте RecursionCount и верните
  2. В противном случае, SpinCount пытается ввести CS по быстрому пути, используя атомные операции на LockCount
  3. В противном случае подождите на LockSemaphore
0 голосов
/ 10 мая 2010

Использование Boost позволит вам выполнять многопоточность и синхронизацию для обеих платформ без набора ifdefs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...