Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.11.25;
Скачать: CL | DM;

Вниз

Синхронизация потоков   Найти похожие ветки 

 
Kerk ©   (2007-10-26 14:09) [0]

Есть в наличии несколько классов типа TMyClass. У них есть метод TMyClass.Execute. Внутри этого метода создается поток, т.е. выполняется он асинхронно.

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

Что-то никак не соображу как организовать подобную синхронизацию. Выносить логику управления потоком наружу не хочется.. он должен сам соображать когда остановиться, дождаться данных и продолжить.


 
Reindeer Moss Eater ©   (2007-10-26 14:12) [1]

Я бы решил посылкой сообщений и флагами в главной форме


 
Reindeer Moss Eater ©   (2007-10-26 14:14) [2]

то есть делаем sendmessage из потока и анализируем результат. Стоять/идти дальше.


 
Ins ©   (2007-10-26 14:15) [3]


> Kerk ©   (26.10.07 14:09)

Варианты:
1. Метод, занесенный в Syncronize, как раз выполняется в главном потоке. Вызвавший поток останавливается и ждет, когда главный освободится и сможет выполнить метод, занесенный в Syncronize. Когда метод выполнится, вызвавший поток возобновится.
2. Отправлять сообщение из дополнительного потока в главный с помощью SendMessage.


 
Ins ©   (2007-10-26 14:16) [4]


> 2. Отправлять сообщение из дополнительного потока в главный
> с помощью SendMessage.

Так как SendMessage возвращает управление после того, как оконная функция его обработает и вернет результат. Именно то, что вам и нужно.


 
radium ©   (2007-10-26 14:17) [5]

Цикл обработки в потоке может проверять значение семафора: ждать определённого его состояния. Пользователь при начале манипуляций семафор блокирует, а по окончании - разблокирует.


 
Kerk ©   (2007-10-26 14:21) [6]


> Reindeer Moss Eater ©   (26.10.07 14:12) [1]

Флаги нужно регулярно перепроверять, а для этого придется синхронизировать потоки

> Ins ©   (26.10.07 14:15) [3]
> Ins ©   (26.10.07 14:16) [4]

Я слабо представляю, как Synchronize или SendMessage будут ждать пока юзер введет какой-то тест или произведет еще какие-нибудь действия с интерфейсом. Если только не ждать способом типа while not Flag do Application.ProcessMessages; в процедуре-обработчике сообщения.

---
Пришло в голову, что можно как-либо передать главной форме уникальный идентификатор для создания Event"а и ждать его...


 
Reindeer Moss Eater ©   (2007-10-26 14:22) [7]

Семафор для одного процесса?
А может лучше тогда решение на базе кластера оракла?


 
Reindeer Moss Eater ©   (2007-10-26 14:23) [8]

Флаги нужно регулярно перепроверять.

Ну как-то же потоки должны узнавать, что им надо постоять и подождать.


 
Ins ©   (2007-10-26 14:24) [9]


> Я слабо представляю, как Synchronize или SendMessage будут
> ждать пока юзер введет какой-то тест или произведет еще
> какие-нибудь действия с интерфейсом.

А, я еще и вопрос невнимательно прочел... Думал вы модальную форму вывести хотите. Тогда событие из главного потока устанавливайте.


 
Kerk ©   (2007-10-26 14:24) [10]


> Reindeer Moss Eater ©   (26.10.07 14:23) [8]

А для этого придется постоянно синхронизировать потоки. ИМХО, не есть гуд.

А мой вариант с Event"ом вообще как смотрится?


 
Reindeer Moss Eater ©   (2007-10-26 14:28) [11]

Одного евента на несколько потоков не хватит


 
Kerk ©   (2007-10-26 14:30) [12]


> Reindeer Moss Eater ©   (26.10.07 14:28) [11]

Для каждого потока будет свой собственный Event


 
Reindeer Moss Eater ©   (2007-10-26 14:31) [13]

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


 
radium ©   (2007-10-26 14:36) [14]

Все потоки должны ждать одного действия пользователя или каждый поток ждёт своё действие?


 
Ins ©   (2007-10-26 14:38) [15]


> Одного евента на несколько потоков не хватит

Если я правильно понял задачу (в чем я уже сомневаюсь), то хватит. Одно событие со сбросом вручную. Все потоки ждут на нем. Делаем из главного SetEvent - все потоки просыпаются. Потом, когда условие перестанет выполняться - сделаем из главного потока ResetEvent.


 
Reindeer Moss Eater ©   (2007-10-26 14:40) [16]

И какой именно поток захавает взведенный евент?
Это ж лотерея.
А они обрабатывают свои порции данных  каждый. Насколько я понял.


 
Kerk ©   (2007-10-26 14:41) [17]


> radium ©   (26.10.07 14:36) [14]

У каждого потока свое действие. Грубо говоря, на форме появится Edit, юзер туда введет что-то и выполнение потока продолжится.


 
Ins ©   (2007-10-26 14:42) [18]


> И какой именно поток захавает взведенный евент?

Если со сбросом вручную - то все. Если с автосбросом - лотерея.


 
Reindeer Moss Eater ©   (2007-10-26 14:43) [19]

самое время уточнить специфику данных и их обработки


 
Ins ©   (2007-10-26 14:44) [20]


> У каждого потока свое действие.

Т.е. правильно ли я понимаю, что каждый поток ждет от пользователя разных действий?


 
Kerk ©   (2007-10-26 14:44) [21]

Каждый поток автономно обрабатывает свои собственные данные. И прерывается для получения своего собственного ответа от юзера.


 
radium ©   (2007-10-26 14:46) [22]


> Kerk ©   (26.10.07 14:44) [21]

Т.е. логика такова, что поток блокирует что-то, что пользователь своим действием освобождает. И это что-то своё для каждого потока. А это что-то можно выбирать - события и пр.


 
Kerk ©   (2007-10-26 14:48) [23]


> radium ©   (26.10.07 14:46) [22]

Вроде подходит только Event. Если мне не изменяет склероз, Mutex может освободить только тот, кто его занял, а семафор - это стрельба из пушки по воробьям.


 
radium ©   (2007-10-26 14:50) [24]

Видимо да. Главное было определиться кто блокирует, а кто освобождает.


 
Eraser ©   (2007-10-26 14:55) [25]


> Kerk ©

запрос к юзеру происходит через специальную форму, которая создается только на время запроса или пользователь должен что-то ввести в основном интерфейсе?


 
Kerk ©   (2007-10-26 14:56) [26]


> Eraser ©   (26.10.07 14:55) [25]

В основном


 
Eraser ©   (2007-10-26 14:59) [27]


> Kerk ©   (26.10.07 14:56) [26]

да.. ну тогда тут уж никак красиво не получится.. максимум как можно оптимизировать  - это оставить только одну связь поток-форма, либо форма-поток, а не обе сразу в структуре классов.


 
Kerk ©   (2007-10-26 15:02) [28]


> Eraser ©   (26.10.07 14:59) [27]

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

Я хочу сделать что-то такое:
Типа продвинутого ЛистБокса... элементы можно будет добавлять в любой момент, удалять после получения ответа и т.п.

============================

Сообщение для юзера 1
Поле ввода 1: __________________

============================

Сообщение для юзера 2
Поле ввода 2: __________________

============================

Сообщение для юзера 3
Поле ввода 3: __________________

============================


 
radium ©   (2007-10-26 15:05) [29]


> Kerk ©   (26.10.07 15:02) [28]

И каждый поток может встать в эту очередь с ожиданием ввода?


 
Kerk ©   (2007-10-26 15:07) [30]


> radium ©   (26.10.07 15:05) [29]

Да, в этом и суть


 
radium ©   (2007-10-26 15:13) [31]

У главной формы есть метод "AddQuestion". Его поток дёргает через синхронайз для добавления вопроса и встаёт на ожидаение объекта синхронизации (эвента, например). Юзер данные вводит и разблокирует объект нажатием Enter :)
Поток перемалывает данные.


 
radium ©   (2007-10-26 15:16) [32]

Только имеется проблема с передачей доп. параметров от потока - текста вопроса, например...


 
Kerk ©   (2007-10-26 15:18) [33]


> radium ©   (26.10.07 15:16) [32]

Ну синхронизоваться разок для передачи данных - это не смертельно
ИМХО, красиво получилось :)


 
Reindeer Moss Eater ©   (2007-10-26 15:20) [34]

Из потока делаем сендмессадж. Всю инфу передаем через указатель на структуру или простой PChar. Главная форма рисует вопрос, взводит евент и передает его назад через эту же структуру, или как результат сендмессадж.


 
radium ©   (2007-10-26 15:21) [35]

Главное, чтобы потоки не задавали вопросы с интервалом 1-2 мс :)



Страницы: 1 вся ветка

Текущий архив: 2007.11.25;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.019 c
2-1193745723
Washington
2007-10-30 15:02
2007.11.25
Шрифт в ListBox е


2-1194094219
Kolan
2007-11-03 15:50
2007.11.25
Как проеделить координаты для DropDownMenu у ToolButton?


15-1192865882
DeBUGger13
2007-10-20 11:38
2007.11.25
DelphiGfx


10-1140499983
rosl
2006-02-21 08:33
2007.11.25
excel


1-1189278923
Efir
2007-09-08 23:15
2007.11.25
Открытие файлов