![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
ЧеловекБорща |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
Доброго времени суток!
Собственно вопрос о TThread. Моя программа должна создавать и поддерживать соединение с устройством в сети постоянно и непрерывно. Как это можно реализовать? Сейчас такого нет, и нормально работать можно только по-отдельности с каждым устройством, без единовременной синхронизации нескольких устройств сразу, чего и надо бы добиться в итоге. Пока в голову приходит следующее: Создать TThread, он существует вечно(сколько мне надо), внути потока находится сетевой компонент, как свойствой вынесенный, при запуске потока, через событие, передается эксемпляр сетевого компонента в класс, следящий за потоком. Все. Класс пользует экземпляр сетевого компонента, и никто, никому не мешает. Как это можно реализовать? Может какие библиотеки для простой реализации такого есть, ил ещё что-нибудь? |
|||
|
||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Неправильно, если в качестве сетевых компонентов рассматривать TServer|ClientSocket и подобные. Всё написанное далее относится именно к этой плеяде. В данном контексте сетевой компонент должен создаваться в методе Execute потока, при этом в потоке должна быть организована выборка сообщений.
Класс должен пользовать потокобезопасные методы потока, создавшего сетевой компонент. Методы и события. А уже сам поток: 1. если нужно передать информацию в соединение: из метода в основном потоке переключается (допустим, через SendMessage) в "себя", и из "себя же" отдает данные сетевому компоненту. 2. Если данные поступили из соединения: из "своего" метода переключается в основной поток, и там вызывает событие приема, которое и ловит нужный компонент. На счет пункта 1 сейчас не уверен, а смотреть немножко лень - возможно, сокеты и нормально воспримут это. Но для пущей безопасности лучше не рисковать. А вот обработка "Классом, пользующим сетевой компонент" данных не в контексте своего потока чревато боком. Как с этим делом обстоит у (к примеру) Indy - не знаю, не умею их готовить ![]() А что в вашем понимании "постоянно и непрерывно"? Сетевой обмен - достаточно медленная операция для современных машин, так что несколько соединений элементарно сможет держать основной поток, без создания дополнительных. |
||||
|
|||||
ЧеловекБорща |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
Именно они, а конкретно блокирующий сокет(Blocking-socket).
Потокобезопасные события я умею делать. А вот как делать методы? События - результат из потока Методы - данные для обработки в поток Я правильно вас понял?
Что вы имеете ввиду под переключением?
Моя программа реализует обмен данными с сетевыми маршрутизаторами(включая им подчиненных), сейчас все происходит в основном потоке, когда происходит запрос передачи/получения, все, включая GUI, зависает в этот момент. Такого не должно быть, и я ищу решение чтобы вынести сокет(виновник торжества) в поток, дабы не тормозил и работал параллельно с оберткой над роутером. |
||||||||
|
|||||||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
ну, например: 1. работа производится в контексте потока, вызвавшего метод
Естественно, в этом примере все обращения к FOutDataList так же должны обрамляться критической секцией. 2. работа производится в контексте "своего" потока, для этого в нем заранее было создано окно:
Второй пример не слишком удачен, но все же... Опс. Я умолкаю - не работаю с сокетами в этом режиме, посему - подсказать нечего. :( Это сообщение отредактировал(а) kami - 14.8.2013, 13:38 |
||||
|
|||||
ЧеловекБорща |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
т.е. все переменные с префиксом F описаны в TThread? НО разве Крит. секция не аналог блок. сокету? Допустимя я загоняю партию из 50 запросов, и каждый раз будет задержка т.к. осн. поток ждет пока крит. секция пустит следующий запрос в обработку. Или я не прав?
Сокеты для меня нечто новое. Я не вижу различия между блокирующим и не блокирующим. Если можете кратро, в 2х словах, рассказать различие, буду рад. Для меня осн. проблема вот в чем:
|
||||||
|
|||||||
ЧеловекБорща |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
Паралельно с большим проектом, пишу маленьки. Программа проверки и контроля баланса аккунта от моего провайдера инета.
Реализовал вашу идею там:
Поток создается при создании гл. окна программы и стартует. Уничтожается при завершении работы программы. Скажите правильно ли я реализовал синхронизацию VCL to Thread? Синхронизацию Thread to VCL я реализую так:
Может есть какие-то замечания? ![]() |
||||
|
|||||
northener |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1361 Регистрация: 2.9.2010 Репутация: 8 Всего: 20 |
Английским владеешь? Вот как описывает эту разницу автор лучшей библиотеки для работы с сокетами (ICS): http://users.telenet.be/sonal.nv/ics/faq/Frame_index.html По этой ссылке General -> 7. Blocking or no blocking, what's the difference Это сообщение отредактировал(а) northener - 15.8.2013, 12:33 -------------------- Но только лошади летают вдохновенно. Иначе лошади разбились бы мгновенно! |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Имхо - не совсем правильно.
1.
У вас создается в основном потоке, а работа с ним ведется в контексте дополнительного. Может быть чревато боком, зависит от внутренней архитектуры THTTPSendEx (кстати, что это?). 2. Не увидел (а может - просто пропустил?) оформление в критическую секцию обращений из потока к переменным, которые могут быть изменены из главного. Помимо этого - попробуйте дважды вызвать Поток, скорее всего, обработает только одну (первую, хотя - не факт, может и только вторую) заявку на логин, т.к. Setting an event that is already set has no effect. Это сообщение отредактировал(а) kami - 15.8.2013, 14:54 |
|||
|
||||
ЧеловекБорща |
|
||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
northener, спасибо за информацию. Познавательно
![]() kami, Так стоп, что-то я не совсем теперь понимаю работу Tthread.
Что есть основной, а что дополнительный? Сейчас я думаю, что TThread это 1 поток. THTTPSendEx - обертка с доп. возможностями над Synapse THTTPSend чтоб легче работать было.
Так вот же:
|
||||||
|
|||||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Эх, много писал, но случайно закрыл страницу...
Основным обычно называют VCL-поток. Дополнительные - все остальные, включая создаваемые с помощью TThread.
C Синапсами не работал, остановился на ICS, посему про внутреннюю их кухню не знаю ничего. А смысл использовать критическую секцию только в одном потоке? Там от нее смысла ноль. Критическая секция не должна допустить изменения данных одним потоком, пока с ним работает другой. А для этого все обращения потоко-небезопасных данных во всех потоках должны оформляться в критическую секцию. Теперь - про
Рассмотрим подробнее: VCL-поток вызывает метод Login, в нем модифицируются приватные переменные потока и взводится Event. Это не значит, что управление моментально переключается на поток, ожидающий событие. Совсем не значит. Управление будет передано потоку тогда, когда это сочтет нужным планировщик потоков Винды. Это же относится к критическим секциям и многому другому (имхо, последняя ОС, которая передавала управление сразу же - XP без какого-то сервиспака). Посему - вполне может получиться так, что событие взведено, основной поток уже вышел из метода Login, а доп.поток так и не приступил к обработке... И если методов типа Login несколько, и они вызываются друг за другом - скорее всего, произойдет замещение одной команды на другую, а первая так и не будет выполнена. Или - другой вариант, основанный на Допустим, что после взвода Event в методе Login переключение потоков произошло сразу же, наш поток приступил к получению данных методом Get. Это - достаточно длительная операция, более того - в ICS для синхронного GET внутри метода идет цикл обработки сообщений. В общем - достаточно долго. При этом основной поток продолжает работу и в процессе выполнения доходит до еще одного метода, в котором должен взвестись Event. Вторичный поток просто не получит эту команду - ведь событие уже было взведено, поток еще находится внутри цикла обработки. |
||||
|
|||||
ЧеловекБорща |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 94 Регистрация: 5.6.2010 Репутация: нет Всего: нет |
Такс, моя задача следующая: Есть объект "Маршрутизатор" надо сделать так, что этот объект не влиял на GUI при сетевых операциях и работал в фоне. т.е. мне надо вынести сокет в TThread. 1 сокет = 1 маршрутизатор Сейчас реализую так же, как в маленьком проекте(код выше), но делаю очередь операций, т.е. чтобы операции 2,3,4 не исчезали если на операции 1 сокет завис. Это сообщение отредактировал(а) ЧеловекБорща - 18.8.2013, 00:20 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |