Остановка двух потоков одним эвентом
От: Hayabusa Россия  
Дата: 21.12.13 22:43
Оценка:
Запостил сюда т.к. использую класс CEvent из ATL.

В общем всю жизнь юзал такую конструкцию, как:


CEvent m_evStop;

// далее в конструкторе
m_evStop(FALSE/*init own*/, FALSE/*manual reset*/)

// в двух потоках ждем этот эвент
while (WAIT_OBJECT_0 != ::WaitForSingleObject(m_evStop, 10)) {/*делаем что-то крайне бесполезное*/}


Каково же было мое удивление, что эвент оказывается сбрасывается функцией WaitForSingleObject и второй поток я рублю с помощью TerminateThread, узнал об этом как добавил логирование..

Как же одним эвентом остановить два потока? Итц поссибл?
Re: Остановка двух потоков одним эвентом
От: Mr.Delphist  
Дата: 21.12.13 23:16
Оценка:
Здравствуйте, Hayabusa, Вы писали:

H>Запостил сюда т.к. использую класс CEvent из ATL.


H>В общем всю жизнь юзал такую конструкцию, как:



H>[ccode]

H>CEvent m_evStop;

H>// далее в конструкторе

H>m_evStop(FALSE/*init own*/, FALSE/*manual reset*/)

CEvent(
BOOL bInitiallyOwn = FALSE,
BOOL bManualReset = FALSE,
LPCTSTR lpszName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL
);

Если я верно понял, то Вы пользуете автоматический сброс события (т.к. для мануального ресета надо вбрасывать второй параметр как TRUE). Далее всё просто — событие поднимает флаг сигнала, его проверяет один из потоков, а затем автоматически сбрасывает. В результате, второй поток понимает, что ему надо продолжать работу до следующего флага (который никто и не собирается взводить).

По идее, цепочка должна быть такая:
* создать событие с параметрами (FALSE, TRUE)
* чего-то происходит
* установить флаг сигнала
* дождаться через join окончания потоков
* сбросить руками флаг сигнала
Re[2]: Остановка двух потоков одним эвентом
От: Hayabusa Россия  
Дата: 22.12.13 07:36
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>По идее, цепочка должна быть такая:

MD>* создать событие с параметрами (FALSE, TRUE)

Логично, я так и пробовал, один из потоков сразу почему то выскакивает (тот, который запускаю первым), как будто эвент установлен
Почему только один из потоков — не понятно..
Re[3]: Остановка двух потоков одним эвентом
От: Alexander G Украина  
Дата: 22.12.13 16:41
Оценка: 2 (1)
Здравствуйте, Hayabusa, Вы писали:

H>Здравствуйте, Mr.Delphist, Вы писали:


MD>>По идее, цепочка должна быть такая:

MD>>* создать событие с параметрами (FALSE, TRUE)

H>Логично, я так и пробовал, один из потоков сразу почему то выскакивает (тот, который запускаю первым), как будто эвент установлен


Потому что есть два разных CEvent.

Один из MFC, с неправильным* порядком параметров, для него (FALSE, TRUE) будет то, что нужно — неустановленное, manual reset.
Другой из ATL, с правильным* порядком параметров, для него (FALSE, TRUE) будет то, что получилось — установленное, auto reset.

* "правильность" относительно соответствующей WinAPI фунции.

То есть, надо поменять параметры местами.

В качестве более дальновидного исправления — написать наследника с перечислениями, а не BOOL'ами в параметрах, уже тогда точно не получится ошибиться.
Параметр bInitialState можно, кстати, и не протягивать в такого наследника — заранее установленное событие нужно чуть чаще, чем никогда.
Русский военный корабль идёт ко дну!
Re[4]: Остановка двух потоков одним эвентом
От: Hayabusa Россия  
Дата: 22.12.13 17:15
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Потому что есть два разных CEvent.


AG>Один из MFC, с неправильным* порядком параметров, для него (FALSE, TRUE) будет то, что нужно — неустановленное, manual reset.

AG>Другой из ATL, с правильным* порядком параметров, для него (FALSE, TRUE) будет то, что получилось — установленное, auto reset.

AG>* "правильность" относительно соответствующей WinAPI фунции.


AG>То есть, надо поменять параметры местами.


AG>В качестве более дальновидного исправления — написать наследника с перечислениями, а не BOOL'ами в параметрах, уже тогда точно не получится ошибиться.

AG>Параметр bInitialState можно, кстати, и не протягивать в такого наследника — заранее установленное событие нужно чуть чаще, чем никогда.

Твоюж.... гребаный ассист показывал сигнатуру с MFC
Спасибо за подсказку я чет и не догадался пройти посмотреть в ATL )
Re[5]: Остановка двух потоков одним эвентом
От: Mr.Delphist  
Дата: 23.12.13 09:34
Оценка: +1
Здравствуйте, Hayabusa, Вы писали:

H>Твоюж.... гребаный ассист показывал сигнатуру с MFC

H>Спасибо за подсказку я чет и не догадался пройти посмотреть в ATL )

Ну что же, у нас снова подтвердились две прописных истины:
1) Ассист — зло
2) MFC — зло

Re[6]: Остановка двух потоков одним эвентом
От: Hayabusa Россия  
Дата: 23.12.13 09:41
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>1) Ассист — зло


я б не сказал, в подавляющем большинстве времени только помогает
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.