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

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.10.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.044 c
2-1190880438
F@T@L_Err0r
2007-09-27 12:07
2007.10.21
messagedlg


4-1176883424
evgenij_
2007-04-18 12:03
2007.10.21
Stay on Top


15-1190123382
Альберт_
2007-09-18 17:49
2007.10.21
какой размер минимального activex ?


2-1191224656
Lexx1
2007-10-01 11:44
2007.10.21
.ini не создается(


2-1191039352
Washington
2007-09-29 08:15
2007.10.21
Что за ошибка?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский