Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки в длл. При вызове Syncronize программа виснет. 
:(
    Опции темы
Bizquit
Дата 9.1.2007, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.10.2005

Репутация: нет
Всего: нет



Основная программа является ядром. Ее задача парсить текстовую информацию поступающую из сокета и раздавать ее плагинам уже в готовой удобоваримой форме. Плагины - обычные ДЛЛки которые подгружаются во время старта программы. С синхронизацией потоков в ядре разобрался. Все норм. А вот плугины по замыслу должны также внутри себя иметь поток, который уже принимает и обрабатывает структурированые данные от ядра. 

Когда данные принимаются плагином они копируются и помещаются в TList. Обрабатывающий поток плагина читает данные из TList'а и делает свою "черную работу". Дык вот если я все правильно понял он должен тоже синхронизироваться при чтении с главным потоком. Но когда я вызываю : Syncronize(GetData);

Код

procedure TPluginWorkThread.GetData;
begin
  ReadedData := nil;          //ReadedData: Pointer
  if DataStorage.Count = 0 then  //DataStorage: TList
    Exit;
  ReadedData := DataStorage[0];
  DataStorage.Delete(0);
end;


Программа виснит наглухо. В чем могут быть грабли?
PM MAIL   Вверх
aktuba
Дата 9.1.2007, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Покажи полный код "плагина", так не понятно...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
MetalFan
Дата 9.1.2007, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



все понятно. смотри код реализации Synchronize у TThread. лучше в DLL его(Synchronize) не использовать.
у приложения и DLL создаются разные критические секции, с пом.которой и выполняется Synchronize.
выход: создать свою критическую секцию и испльзовать ее при передачи данных в/из поток(а).
пример - смотри Classes.

Это сообщение отредактировал(а) MetalFan - 9.1.2007, 12:39


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Bizquit
Дата 9.1.2007, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.10.2005

Репутация: нет
Всего: нет



Цитата(aktuba @  9.1.2007,  12:21 Найти цитируемый пост)
Покажи полный код "плагина", так не понятно...

А что конкретно не понятно? Просто там много рутины не относящейся к вопросу. Не думаю что это хорошая идея постить полный код  smile 


Цитата(MetalFan @  9.1.2007,  12:36 Найти цитируемый пост)
все понятно. смотри код реализации Synchronize у TThread. лучше в DLL его(Synchronize) не использовать.у приложения и DLL создаются разные критические секции, с пом.которой и выполняется Synchronize.выход: создать свою критическую секцию и испльзовать ее при передачи данных в/из поток(а).пример - смотри Classes.

ОК. Спасибо. Обязательно гляну. 

то есть у меня и была идея сделать нечто следущее:
в самой длл объявить внутреннюю процедуру что-то типа того:

Код

procedure TransferData(Direction: TDirection; var Data: Pointer);
begin
  EnterCriticalSection;

  if Direction = dInList then
     Положить в лист
  else //Direction = dFromList
    Забрать из листа

  LeaveCriticalSection
end;


И когда придут данные в плугин - вызывать эту процедуру. И из потока для чтения пришедших данных  вызывать эту же процедуру без Synchronize. Так?

Это сообщение отредактировал(а) Bizquit - 9.1.2007, 13:08
PM MAIL   Вверх
MetalFan
Дата 9.1.2007, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Bizquit, потчи так. только надо ее инициализировать и не забыть освободить.
объявить поле типа FCS: TRTLCriticalSection
InitializeCriticalSection(FCS) - инициализация КС. можно при создании потока/менеджера потоков
ну и во вход и выход передать не забыть
DeleteCriticalSection(FCS) - удаление КС. соотв. при уничтожении.

Это сообщение отредактировал(а) MetalFan - 9.1.2007, 13:27


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Bizquit
Дата 9.1.2007, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.10.2005

Репутация: нет
Всего: нет



MetalFan, Пасиб, помог.
PM MAIL   Вверх
Bizquit
Дата 10.1.2007, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 4.10.2005

Репутация: нет
Всего: нет



Кстати, а вот еще нюанс, как лучше сделать? 
В ядре есть поток(TSenderThread), который просматривает TList в котором лежат результаты парсинга, и который эти результаты рассылает плагинам. Чтобы отослать результат, он вызывает функцию ДЛЛки SendData(Data: PEventData). Эта функция в дллке кладет копию данных в свой TList. Дык вот надо ли вызывать SendData обернутое в Syncronize? Или это не обязательно? Может просто ее в потоке TSenderThread вызывать без синхронизации с основным потоком, а она уже в ДЛЛке синхронизуясь там со своим потоком будет класть данные в TList?
Не слишком сумбурно получилось? smile
PM MAIL   Вверх
MetalFan
Дата 10.1.2007, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



для чего нужен Synchronize представляешь?
для выполнения кода в контексте главного потока приложения.
почему? чтобы не допустить одновременного обращения к одним данным (в частности VCL контролам, созданных в главном потоке)

что получается при использовании критической секции?
код, который находится между входом и выходом, единовременно может выполниться только в одном потоке.
т.е. при вызове EnterCriticalSection, если счетчик вызовов <>0, то система замораживает данный поток до тех пор, пока
другой поток, что "вошел" в данную КС не выйдет из нее. но тут главное избежать DeadLock'ов

поняли, к чему веду?

з.ы. если я не прав, поправьте ;)


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.