Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.11.25;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.046 c
3-1183999224
Yurij-7
2007-07-09 20:40
2007.11.25
FireBird Export and Import Data


15-1193402767
Alien1769
2007-10-26 16:46
2007.11.25
Работа с модемом


15-1193390167
Avds
2007-10-26 13:16
2007.11.25
Хук на FullScreen?


1-1188972200
MZ
2007-09-05 10:03
2007.11.25
Главное меню используя ToolBar2000


2-1193993515
vl
2007-11-02 11:51
2007.11.25
Добавление данных в таблицу





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский