![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Вечер добрый. Вот надыбал ситуацию, когда Mutex ведет себя не так как хотелось бы. Точнее даже не Mutex, а WaitForSingleObject
Вот код
По задумке потоки ждут нажатия кнопки оператором, для того чтобы начать вывод. Однако этого не происходит - выводится все три надписи сразу. В описании функции WaitForSingleObject вычитал (DRKB), что она каким-то образом прекращает ожидание, если поток завершился и при этом даже НЕ освободил Mutex. Кто посоветует, как это обойти? Как сделать, чтобы, несмотря на то что выполнение Execute закончилось, остальные потоки все равно ждали ПРЯМОГО УКАЗАНИЯ что можно выводить (ReleaseMutex(Mutex);)? Заранее спасибо. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Опять же все обращения к VCL из второго потока можно делать только через Syncronize, все остальные вызовы опасны.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
использовать событие (event) вместо мьютекса
-------------------- Обижено школьников: 8 |
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Event мне нельзя или я просто не знаю как его применить к такому случаю. Здесь сотни потоков ожидают одного события - освобождения оператора. Насколько я понимаю, такая ситуация решается именно мьютексами. Если я не прав - поправь плз.
Если это не долго и тебе не сложно, приведи пример плз. Достаточно не программы, а двух ключевых операторов - типа там создаем семафор/мьютекс/т.п, там ждем того-то. Это сообщение отредактировал(а) Ibragim - 14.12.2006, 02:24 |
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Даже не так. Вот исходник тестовой проги. Единственое обращение к VCL через Syncronize. Эффект тот же. Чего посоветуете?
|
|||
|
||||
bems |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
А если с событием тогда 1. создал событие (CreateEvent). 2. создал потоки, вызывающие WaitForSingleObject с хэндлом события 3. по нажатию кнопки (как в примере) вызываешь SetEvent 4. все ждущие потоки выполняются дальше Добавлено @ 03:33
если эта процедура действительно вызывается как обработчик события (читай - из главного VCL потока) то тут ты пытаешся освободить мьютекс которым не владеешь. -------------------- Обижено школьников: 8 |
||||
|
|||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
вот тут false означает, что у вновь созданного мьютекса нет владельца. Раз так, то один из трех одинаковых потоков (который первым доберется до вызова WaitForSingleObject) моментально его дождется и захватит. Пока он будет рисовать надпись (ну или просто присваивать строку) другие два будут ждать. Когда он выйдет не освободив мьютекса, мьютекс будет щитаться брошенным и его дождется (захватит) слудующий поток
Вобщем нужный эффект будет если ты тутзаменишь false на true. Тогда владельцем свежего мьютекса будет поток который его создал (первичный поток процесса, VCL - поток). По нажатию кнопки он же его освободит, и по очереди(!!!!!!!) начнут просыпаться те три потока (один сделал дело и завершился - проснулся другой) Будет выглядеть как будто они проснулись одновременно, поскольку работают очень не долго. Но более правильно будет тут использовать эвент, а мьютексы оставить для случая когда ни один из этих трех потоков не должен что-то делать одновременно с другими (MUTual EXclusive access - взаимоисключающий доступ) -------------------- Обижено школьников: 8 |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
и для синхронизации в пределах одного процесса есть более быстрые способы чем объекты ядра. Смотри критические секции и interlocked-функции
-------------------- Обижено школьников: 8 |
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Большое спасибо bems !
Все гуд, разобрался. На всякий случай (для тех у кого возникнет такой же вопрос) напишу как сделал. 1. В одном из потоков TThread (менеджер потоков, ссылку на него и так имели ВСЕ потоки) создал переменную - объект TCriticalSection. 2. Везде, где потокам нужно было для продолжения, завершения работы, показа результатов выполнения и т.д. (у меня около 500 потоков, причем более 20 классов - "видов" потоков) вмешательство оператора - Enter в эту CriticalSection. После - Leave. Работает, даже если Leave вызывается из совершенно другого потока, а тот который сказал Enter давно завершен. Все, тему можно считать закрытой, спасибо всем особенно bems. PS Много предупреждений насчет обращений к визуальным компонентам из-под других потоков. Точно проверено (оч. громоздкие задачи, прямо стресс-тест ![]() 1. Все нормально без всякой синхронизации работает если писать/читать поля TStringGrid, естественно, не одно поле одновременно. 2. Отлично работает TMemo.Add 3. Отлично работает StatusBar |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
это тебе пока везет. НЕЛЬЗЯ! -------------------- Обижено школьников: 8 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |