| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Удерживать TThread постоянно |
| Автор: ЧеловекБорща 14.8.2013, 09:27 |
| Доброго времени суток! Собственно вопрос о TThread. Моя программа должна создавать и поддерживать соединение с устройством в сети постоянно и непрерывно. Как это можно реализовать? Сейчас такого нет, и нормально работать можно только по-отдельности с каждым устройством, без единовременной синхронизации нескольких устройств сразу, чего и надо бы добиться в итоге. Пока в голову приходит следующее: Создать TThread, он существует вечно(сколько мне надо), внути потока находится сетевой компонент, как свойствой вынесенный, при запуске потока, через событие, передается эксемпляр сетевого компонента в класс, следящий за потоком. Все. Класс пользует экземпляр сетевого компонента, и никто, никому не мешает. Как это можно реализовать? Может какие библиотеки для простой реализации такого есть, ил ещё что-нибудь? |
| Автор: ЧеловекБорща 14.8.2013, 10:16 | ||||||||
Именно они, а конкретно блокирующий сокет(Blocking-socket).
Потокобезопасные события я умею делать. А вот как делать методы? События - результат из потока Методы - данные для обработки в поток Я правильно вас понял?
Что вы имеете ввиду под переключением?
Моя программа реализует обмен данными с сетевыми маршрутизаторами(включая им подчиненных), сейчас все происходит в основном потоке, когда происходит запрос передачи/получения, все, включая GUI, зависает в этот момент. Такого не должно быть, и я ищу решение чтобы вынести сокет(виновник торжества) в поток, дабы не тормозил и работал параллельно с оберткой над роутером. |
| Автор: kami 14.8.2013, 13:37 | ||||
ну, например: 1. работа производится в контексте потока, вызвавшего метод
Естественно, в этом примере все обращения к FOutDataList так же должны обрамляться критической секцией. 2. работа производится в контексте "своего" потока, для этого в нем заранее было создано окно:
Второй пример не слишком удачен, но все же... Опс. Я умолкаю - не работаю с сокетами в этом режиме, посему - подсказать нечего. :( |
| Автор: ЧеловекБорща 14.8.2013, 13:48 | ||||||
т.е. все переменные с префиксом F описаны в TThread? НО разве Крит. секция не аналог блок. сокету? Допустимя я загоняю партию из 50 запросов, и каждый раз будет задержка т.к. осн. поток ждет пока крит. секция пустит следующий запрос в обработку. Или я не прав?
Сокеты для меня нечто новое. Я не вижу различия между блокирующим и не блокирующим. Если можете кратро, в 2х словах, рассказать различие, буду рад. Для меня осн. проблема вот в чем:
|
| Автор: ЧеловекБорща 15.8.2013, 11:19 | ||||
| Паралельно с большим проектом, пишу маленьки. Программа проверки и контроля баланса аккунта от моего провайдера инета. Реализовал вашу идею там:
Поток создается при создании гл. окна программы и стартует. Уничтожается при завершении работы программы. Скажите правильно ли я реализовал синхронизацию VCL to Thread? Синхронизацию Thread to VCL я реализую так:
Может есть какие-то замечания? |
| Автор: northener 15.8.2013, 12:32 | ||
Английским владеешь? Вот как описывает эту разницу автор лучшей библиотеки для работы с сокетами (ICS): http://users.telenet.be/sonal.nv/ics/faq/Frame_index.html По этой ссылке General -> 7. Blocking or no blocking, what's the difference |
| Автор: kami 15.8.2013, 14:52 | ||
| Имхо - не совсем правильно. 1.
У вас создается в основном потоке, а работа с ним ведется в контексте дополнительного. Может быть чревато боком, зависит от внутренней архитектуры THTTPSendEx (кстати, что это?). 2. Не увидел (а может - просто пропустил?) оформление в критическую секцию обращений из потока к переменным, которые могут быть изменены из главного. Помимо этого - попробуйте дважды вызвать Поток, скорее всего, обработает только одну (первую, хотя - не факт, может и только вторую) заявку на логин, т.к. http://msdn.microsoft.com/en-us/library/windows/apps/ms686211(v=vs.85).aspx |
| Автор: ЧеловекБорща 15.8.2013, 15:02 | ||||||
| northener, спасибо за информацию. Познавательно kami, Так стоп, что-то я не совсем теперь понимаю работу Tthread.
Что есть основной, а что дополнительный? Сейчас я думаю, что TThread это 1 поток. THTTPSendEx - обертка с доп. возможностями над Synapse THTTPSend чтоб легче работать было.
Так вот же:
|
| Автор: kami 15.8.2013, 20:48 | ||||
| Эх, много писал, но случайно закрыл страницу... Основным обычно называют VCL-поток. Дополнительные - все остальные, включая создаваемые с помощью TThread.
C Синапсами не работал, остановился на ICS, посему про внутреннюю их кухню не знаю ничего. А смысл использовать критическую секцию только в одном потоке? Там от нее смысла ноль. Критическая секция не должна допустить изменения данных одним потоком, пока с ним работает другой. А для этого все обращения потоко-небезопасных данных во всех потоках должны оформляться в критическую секцию. Теперь - про
Рассмотрим подробнее: VCL-поток вызывает метод Login, в нем модифицируются приватные переменные потока и взводится Event. Это не значит, что управление моментально переключается на поток, ожидающий событие. Совсем не значит. Управление будет передано потоку тогда, когда это сочтет нужным планировщик потоков Винды. Это же относится к критическим секциям и многому другому (имхо, последняя ОС, которая передавала управление сразу же - XP без какого-то сервиспака). Посему - вполне может получиться так, что событие взведено, основной поток уже вышел из метода Login, а доп.поток так и не приступил к обработке... И если методов типа Login несколько, и они вызываются друг за другом - скорее всего, произойдет замещение одной команды на другую, а первая так и не будет выполнена. Или - другой вариант, основанный на Допустим, что после взвода Event в методе Login переключение потоков произошло сразу же, наш поток приступил к получению данных методом Get. Это - достаточно длительная операция, более того - в ICS для синхронного GET внутри метода идет цикл обработки сообщений. В общем - достаточно долго. При этом основной поток продолжает работу и в процессе выполнения доходит до еще одного метода, в котором должен взвестись Event. Вторичный поток просто не получит эту команду - ведь событие уже было взведено, поток еще находится внутри цикла обработки. |
| Автор: ЧеловекБорща 18.8.2013, 00:18 | ||
Такс, моя задача следующая: Есть объект "Маршрутизатор" надо сделать так, что этот объект не влиял на GUI при сетевых операциях и работал в фоне. т.е. мне надо вынести сокет в TThread. 1 сокет = 1 маршрутизатор Сейчас реализую так же, как в маленьком проекте(код выше), но делаю очередь операций, т.е. чтобы операции 2,3,4 не исчезали если на операции 1 сокет завис. |