![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| Alca |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Принцип работы пула:
- Есть пул потоков (класс CXThreadPool порожденный от CXThread). - Есть виртуальный метод uiOnRun (я его переопределяю в данном пуле CXThreadPool), в котором я поочереди запускаю потоки (задания) и добавляю указатели на эти потоки в std::list. - Затем в том же uiOnRun жду окончания работы всех потоков на методе bWaitGroup (врапер над WaitForSingleObject). - Когда поток отработал, он самоуничтожается (т.е. delete pPtr_ToThread делать не надо) и удаляется соотв-щий указатель на объект потока из std::list. !!! Вот в чём затык !!! : - когда я жду на bWaitGroup, какой-то поток начинает завершаться (начинает работать метод _vOnExitTask) и т.к. все операции с std::list я лочу крит. секцией (CXCriticalSectionLocker, т.е. лок действует до конца блока), то возникает дедлок. При использование метода bExitGroup(INFINITE):
получаю такой лог:
Как мне решить эту проблему, может выстроить другую архитектуру пула? Вот исходники:
Это сообщение отредактировал(а) Alca - 13.1.2010, 13:47 |
||||||
|
|||||||
| Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Если я правильно поняла: во время ожидания у тебя список заблокирован и именно это является причиной deadlock, т.к. поток не может себя удалить.
Самое логичное - избавиться от блокировки на время ожидания. Жто и само по себе вредно, все блокировки должны быть короткими. Например, скопировать список (т.е. хандлы потоков и ждать их). Но я вообще не понимаю, зачем тебе ждать через WaitForSingleObject. Почему не Multiple? -------------------- ... |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 8 Всего: 154 |
||||
|
||||
| Alca |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Т.к. залочен std::list и поток не может себя удалить из списка
Потому что WaitForMultipleObjects может ждать не больше 64-х хендлов и поэтому все равно прийдется крутить цикл. (позже переделаю все-таки на мальтипл).
Тогда вылетают STL-вские эссерты
thread pool api не использкется, хочу сваять без него и к тому же, еще не разобрался в IOCP. Это сообщение отредактировал(а) Alca - 13.1.2010, 14:17 |
||||||||
|
|||||||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
семафор нужно поставить...
1. создаем семафор на N единиц 2. создаем N потоков 3. каждый поток, при завершении, вызывает WaitForSingleObject для этого семафора 4. после чего можно выполнять vBtnExitGroup_... и т.п., т.е. после Wait'а все семафоры точно прошли "тело", это называется барьер (barrier) если нужно динамически увеличить число потоков, вызываем ReleaseSemaphore с числом добавляемых потоков Добавлено через 3 минуты и 49 секунд блин щас подумаем... -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Так он у меня и есть (_m_semSemaphore). Добавлено @ 14:27 Первые три пункта у меня так и работают, а vBtnExitGroup_OnClick() вызывается из главного (основного) потока (это кнопка на окне). Это сообщение отредактировал(а) Alca - 13.1.2010, 14:29 |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
не не, я же говорю, перепутал
где-то у нас тут была реализация обратного семафора принцип где-то такой:
Добавлено через 1 минуту и 28 секунд hBarrier - неавтомат -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
и что он должен делать? Смысл какой? |
|||
|
||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
значит надо сделать в vBtnExitGroup_OnClick ожидание прохода барьера, для моего варианта это будет так:
Добавлено @ 14:59 смысл - сигнализировать когда счетчик нулевой стандартный семафор сигнализирует пока счетчик ненулевой Это сообщение отредактировал(а) GremlinProg - 13.1.2010, 15:00 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
и что это даст в моем случае? Добавлено через 40 секунд Объясни алгоритм, пж. |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
это не ожидание, это обрыв семафора, т.е. блокировка всех оставшихся в нем единиц одним махом _InterlockedExchange при этом вернет число потоков, которые не прошли барьер для ожидания в vBtnExitGroup_OnClick, надо прокрутить WaitForSingleObject для дополнительного семафора N раз, а в постобработку каждого потока добавить ReleaseSemaphore на единицу Добавлено @ 15:26 в твоем случае ( когда vBtnExitGroup_OnClick - в основном потоке) достаточно будет сделать последнее:
если кроме vBtnExitGroup_OnClick критических мест нет, то барьер (на обратном семафоре) в потоках уже будет не нужен Это сообщение отредактировал(а) GremlinProg - 13.1.2010, 15:41 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
хорошо объяснил: сам с собой поспорил, исправил, разве что не наказал :)
это будет означать, что цикл в основном потоке завершится только тогда, когда все N потоков вызовут ReleaseSemaphore, т.е., что называется, "пройдут барьер" -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
GremlinProg, спасибо. Буду разбираться.
|
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |