Всем привет. Как правильно синхронизировать 2 потока? Т.е. Есть переменная, 1 поток ее инкрементит, другой декрементит. Задача, чтоб ее значение не изменялось. Ну т.е. чтоб они по очереди работали. Почитал МСДН, нашел методы SuspendThread/ResumeThread НО: Если я делаю просто вот так: Код (Text): Thread1 PROC num:LPVOID .while TRUE inc number Invoke ResumeThread,hThread2 Invoke SuspendThread,hThread1 .endw ret Thread1 ENDP Thread2 PROC num:LPVOID .while TRUE dec number Invoke ResumeThread,hThread1 Invoke SuspendThread,hThread2 .endw ret Thread2 ENDP То эти потоки выполняются по 1 разу и засыпают оба. Почитал МСДН Нашел то, что SuspendThread, инкрементит число сна, и поток не оживет, пока оно не станет равно 0. Так же узнал, что метод ResumeThread возвращает это число сна, до того как уменьшить его на 1. Переделал код: Код (Text): Thread1 PROC num:LPVOID .while TRUE inc number .while TRUE Invoke ResumeThread,hThread2 .break .if eax==1 .endw Invoke SuspendThread,hThread1 .endw ret Thread1 ENDP Thread2 PROC num:LPVOID .while TRUE dec number .while TRUE Invoke ResumeThread,hThread1 .break .if eax==1 .endw Invoke SuspendThread,hThread2 .endw ret Thread2 ENDP Все заработало. НО: Я вывожу каждую секунду в третем потоке, 2 числа, сколько отработали раз эти 2 потока. Вывожу на консоль. Так вот, когда эта консоль не активна, то каждый поток, отрабатывает ~по 10 000 раз, а как только я нажимаю на консоль и активирую ее, потоки начинают обрабатывать по 3-5 цикла в секунду )) Вот такая вот штука. Помогите плиз!
По очереди? Можно на критических секциях, можно на ядерных объектах (мьютексы, семафоры, события), можно придумать что-то своё.
Спасибо, но скажите еще что-нибудь про мои примеры. Почему так происходит? И еще, как сделать что-то типа wait, который будет просыпаться по команде? Я нашел CreateMutex и WaitForSingleObject, но что это так и не понял... т.к. этот Wait нифига не ждет.
Смотри описание WaitForSingleObject - какие объекты он может "ждать" и выбирай любой из них. По мьютексам - можно сделать следующее: * создание мьютекса в основном потоке, bInitialOwner = false * создание потоков с передачей им хэндла мьютекса либо просто использовать глобальную переменную * в потоке: ** попытка захватить мьютекс через WaitForSingleObject(g_hMutex, INFINITE). Т.к. он изначально создан не захваченным, то первый поток захватит его. ** изменение переменной ** освобождение мьютекса с помощью ReleaseMutex ** Sleep(n), чтобы гарантированно отдать время другому потоку ** переход обратно к ожиданию, если у тебя потоки в цикле работают с переменной * во втором потоке происходит то же самое: попытка захвата и ожидание, если другой поток уже захватил мьютекс; работа с переменной; освобождение и т.п.