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

Вниз

Межпотоковое взаимодействие: есть поток, который при   Найти похожие ветки 

 
AlexEgorov   (2007-04-24 09:41) [0]

поступленнии данных создаёт другой поток для их обработки и продолжает ждать новые данные. Как из второго потока вернуть обработанные данные в первый поток в сервисе? Если работа идёт в приложении, то Sinchronyze - и никаких проблем, а в сервисе это не прокатывает, наверное из-за того, что нет главной формы, в контексе которой работает код в Sinchronyze. Что можно сделать в сервисе?


 
MBo ©   (2007-04-24 09:46) [1]

второй поток кладет данные в некий буфер и выставляет объект синхронизации, например, Event, а первый поток, дождавшись срабатывания, забирает данные


 
Сергей М. ©   (2007-04-24 09:49) [2]

Mожно также воспользоваться PostThreadMessage, если взаимодействие с раб.столом по каким-то причинам нежелательно. Иначе - SendMessage


 
AlexEgorov   (2007-04-24 09:58) [3]

Сейчас у меня сделано так - после обработки данных второй поток перебирает список потоков поступающих данных (на самом деле их несколько), и устанавливает в нём Event, предварительно положив обработанные данные в некий буфер, как и предложил MBo.

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


 
Reindeer Moss Eater ©   (2007-04-24 10:02) [4]

так вот похоже в какой-то момент эта сейция не освобождается и всё останавливается, т.к. все новые потоки обработки данных ждут освобождения секции, которая залочена :(

Наверное у тебя есть ошибка в программе


 
Сергей М. ©   (2007-04-24 10:04) [5]


> AlexEgorov   (24.04.07 09:58) [3]


Я так понял, что у тебя один обрабатывающий поток на несколько транспортных ?

Странная, однако, затея - "семеро с ложкой, один с сошкой")


 
AlexEgorov   (2007-04-24 10:08) [6]

Я хотел сначала на каждый станспортный делать обрабатывающий, но в этом случае спулер входит в ступор :( - я мониторю входящие задания печати, и транспортные потоки, это потоки мониторинга принтеров. А обрабатывающий поток выдёргивает и парсит эти задания.


 
MBo ©   (2007-04-24 10:11) [7]

может, воспользоваться TMultiReadExclusiveWriteSynchronizer?


 
AlexEgorov   (2007-04-24 10:13) [8]

А в каком из потоков? Мне же как-раз множественное чтение для нескольких обрабатывающих потоков ненужно, т.к. спулер вешается.


 
Сергей М. ©   (2007-04-24 10:15) [9]


> спулер входит в ступор


Это как ?


 
AlexEgorov   (2007-04-24 10:17) [10]

> Это как ?

Начинает сильно тормозить - рассматривается ситуация, когда принтеров в системе более 50-ти и задания печати поступают довольно часто


 
Сергей М. ©   (2007-04-24 10:18) [11]

Какой поток у тебя вызывает EnumJobs, а какой Get/Set/AddJob ?


 
AlexEgorov   (2007-04-24 10:21) [12]

Я обрабатываю все задания печати через FindFirst/NextPrinterChangeNotification в транспортном потоке, там же поступившее задание ставится в паузу и создаётся обрабатывающий поток, котоый парсит новое задание печати и возвращает результат в транспортный поток, после этого транспортный поток делает заданию Resume, а после того, как задание напечатано, сохраняет данные о задании и ждёт следующие


 
Сергей М. ©   (2007-04-24 10:33) [13]

Pausing a printer suspends scheduling of all print jobs for that printer, except for the one print job that may be currently printing.

Что на это скажешь ?


 
AlexEgorov   (2007-04-24 10:34) [14]

Нет, паузится не принтер, а задание печати, которое нужно парсить


 
Сергей М. ©   (2007-04-24 10:35) [15]

Каким образом ?


 
AlexEgorov   (2007-04-24 10:38) [16]

> Каким образом ?

Приходит сообщение о новом задании печати в очереди и я ставлю задание в паузу SetJob(...). Потом дожитаюсь собития, что задание полностью встало в очередь (спулинг закончился) после этого вызываю обрабатывающий поток и продолжаю мониторить задания печати


 
Сергей М. ©   (2007-04-24 10:46) [17]

А на каком этапе спулер начинает "тормозить" ?


 
AlexEgorov   (2007-04-24 10:52) [18]

Если каждый транспортный поток создаст свой обрабатывающий, то все они ломанутся на чтение содержимого заданий печати - вот тут и возникает торможение, особенно если задание печати здоровые (а они для плоттеров от сотни мегабайт идут). Для этого и сделан один обрабатывающий поток.


 
Сергей М. ©   (2007-04-24 10:54) [19]


> то все они ломанутся на чтение содержимого заданий печати


Так ты защити процедуру чтения крит.секцией - и всех делов ..


 
Сергей М. ©   (2007-04-24 10:57) [20]

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

Либо перенеси чтение в трансп.поток (тогда защита крит.секцией не нужна), либо, как уже сказано, защищай чтение со стороны нескольких обр.потоков крит.секцией.


 
AlexEgorov   (2007-04-24 11:02) [21]

> Так ты защити процедуру чтения крит.секцией - и всех делов ..

Так я и сделал:

   EnterCriticalSection(csJobsThread);
   try
     ParseJob(Job)
   finally
     LeaveCriticalSection(csJobsThread);
   end;


Но похоже, по какой-то причине в определённый момент не срабатывает LeaveCriticalSection и обрабатывающие потоки начинают копиться :(

> Либо перенеси чтение в трансп.поток

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


 
Сергей М. ©   (2007-04-24 11:11) [22]


> по какой-то причине в определённый момент не срабатывает
> LeaveCriticalSection


Такого быть не может ...

Покажи, что у тебя творится в теле ParseJob ..


 
AlexEgorov   (2007-04-24 11:42) [23]

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


 
Сергей М. ©   (2007-04-24 11:46) [24]


> Там кода много с вызовом сопутствующих функций


А весь код и не нужен.

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


 
AlexEgorov   (2007-04-24 12:01) [25]

Сначала вызывается
OpenPrinterW(PWideChar(PrnName + ",Job " + IntToWideStr(JobId)), hPrn, nil);
потом читается всё задание функцией ReadPrinter с записью прочитанного в файл, параллельно с этим происходит парсинг, т.е. в процессе чтения. Там для разных типов заданий разные методы парсинга.


 
AlexEgorov   (2007-04-24 12:01) [26]

Сначала вызывается
OpenPrinterW(PWideChar(PrnName + ",Job " + IntToWideStr(JobId)), hPrn, nil);
потом читается всё задание функцией ReadPrinter с записью прочитанного в файл, параллельно с этим происходит парсинг, т.е. в процессе чтения. Там для разных типов заданий разные методы парсинга.


 
Сергей М. ©   (2007-04-24 12:05) [27]


> потом читается всё задание функцией ReadPrinter


Не понял ..

Почему не GetJob ?


 
AlexEgorov   (2007-04-24 12:55) [28]

Потому что мне нужно просмотреть именно содержимое задания печати, т.к. в JOB_INFO_* не всегда нужная информация есть, например количество копий для заданий отправленных из Word или для заданий отравленный с Linux/Mac/Solaris, или для заданий отправленных через IPP. В общем много случаем, когда GetJob не может помочь


 
Сергей М. ©   (2007-04-24 13:11) [29]


> много случаем, когда GetJob не может помочь
>


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


 
AlexEgorov   (2007-04-24 13:55) [30]

Понятно, попробую парсинг вообще пока заменить пустыкой и пользователю отправить на тест, у меня-то всё работает на сервере с >100 принтеров и по несколько заданий в секунду... А у него и нагрузка меньше и принтеров меньше, а тем не менее возникает странная ситуация



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

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

Наверх




Память: 0.54 MB
Время: 0.019 c
15-1190093011
boriskb
2007-09-18 09:23
2007.10.21
Домен su живет и побеждает


2-1190627006
misha_gr
2007-09-24 13:43
2007.10.21
TClientDataSet.Locate


15-1190652765
terc
2007-09-24 20:52
2007.10.21
HTML


3-1182153666
mefodiy
2007-06-18 12:01
2007.10.21
SQL запрос с использованием LIKE


2-1190619226
YakovlevAP
2007-09-24 11:33
2007.10.21
Как сделать прогу типа ASTER ?