Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

взаимодействие двух программ

15K
02 мая 2006 года
DubAlex
10 / / 26.04.2006
Есть две программы: P1 и P2. P1 выполняет какие-то действия и результат записывает в файл F1. P2 через некоторые интервалы времени читает из файла F1 записанное ранее значение и выводит его на экран.
Можно ли обойтись без файла, т.е. в идеале программа P1 передает результат программе P2 и та сразу выводит этот результат на экран?
406
02 мая 2006 года
vitaly2003s
481 / / 27.07.2004
Цитата:
Originally posted by DubAlex
Есть две программы: P1 и P2. P1 выполняет какие-то действия и результат записывает в файл F1. P2 через некоторые интервалы времени читает из файла F1 записанное ранее значение и выводит его на экран.
Можно ли обойтись без файла, т.е. в идеале программа P1 передает результат программе P2 и та сразу выводит этот результат на экран?


Существует много методов взаимодействия между процессами. Вот что пишет MSDN по этому поводу:

Interprocess Communications

The Microsoft® Windows® operating system provides mechanisms for facilitating communications and data sharing between applications. Collectively, the activities enabled by these mechanisms are called interprocess communications (IPC). Some forms of IPC facilitate the division of labor among several specialized processes. Other forms of IPC facilitate the division of labor among computers on a network.

Typically, applications can use IPC categorized as clients or servers. A client is an application or a process that requests a service from some other application or process. A server is an application or a process that responds to a client request. Many applications act as both a client and a server, depending on the situation. For example, a word processing application might act as a client in requesting a summary table of manufacturing costs from a spreadsheet application acting as a server. The spreadsheet application, in turn, might act as a client in requesting the latest inventory levels from an automated inventory control application.

After you decide that your application would benefit from IPC, you must decide which of the available IPC methods to use. It is likely that an application will use several IPC mechanisms. The answers to these questions determine whether an application can benefit by using one or more IPC mechanisms.

Should the application be able to communicate with other applications running on other computers on a network, or is it sufficient for the application to communicate only with applications on the local computer?
Should the application be able to communicate with applications running on other computers that may be running under different operating systems (such as 16-bit Windows or UNIX)?
Should the user of the application have to choose the other application(s) with which the application communicates, or can the application implicitly find its cooperating partners?
Should the application communicate with many different applications in a general way, such as allowing cut and paste operations with any other application, or should its communications requirements be limited to a restricted set of interactions with specific other applications?
Is performance a critical aspect of the application? All IPC mechanisms include some amount of overhead.
Should the application be a GUI application or a console application? Some IPC mechanisms require a GUI application.

The following IPC mechanisms are supported by Windows:

Clipboard
COM
Data Copy
DDE
File Mapping
Mailslots
Pipes
RPC
Windows Sockets

534
02 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by vitaly2003s
The following IPC mechanisms are supported by Windows:

Clipboard
COM
Data Copy
DDE
File Mapping
Mailslots
Pipes
RPC
Windows Sockets

С помощью SendMessage/PostMessage уведомляем процесс о поступлении новых данных, а сами данные размещаем в проецируемом в память файле. Такова обычная схема взаимодействия процессов, всё достаточно просто и красиво.

3
02 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
С помощью SendMessage/PostMessage уведомляем процесс о поступлении новых данных, а сами данные размещаем в проецируемом в память файле. Такова обычная схема взаимодействия процессов, всё достаточно просто и красиво.


SendMessage/PostMessage - некрасиво, т.к. механизм обмена данными привязывается к механизму оконных сообщений, который сам по себе не быстрый.
Лучше использовать глобальные объекты синхронизации или уже готовые механизмы типа pipes.

534
02 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
SendMessage/PostMessage - некрасиво, т.к. механизм обмена данными привязывается к механизму оконных сообщений, который сам по себе не быстрый.
Лучше использовать глобальные объекты синхронизации или уже готовые механизмы типа pipes.

Ну, глобальные объекты синхронизации потребуют выделения отдельного потока для отображения результатов, даже если это всего десяток операций. А вот именованные пайпы - это тема, хотя я лично предпочитаю file mapping, поскольку могу обратится к любому участку разделяемых данных в любой момент времени.

3
02 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
Ну, глобальные объекты синхронизации потребуют выделения отдельного потока для отображения результатов, даже если это всего десяток операций.


Зачем?!!

Цитата:
Originally posted by HarryAxe
А вот именованные пайпы - это тема, хотя я лично предпочитаю file mapping, поскольку могу обратится к любому участку разделяемых данных в любой момент времени.


pipe - это тот же FM + глоб. объект синхронизации

534
02 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Зачем?!!

Ну так ожидать-то объект нужно будет с помощью Wait-функции, а основной поток тормозить нецелесообразно.

Цитата:
Originally posted by Green
pipe - это тот же FM + глоб. объект синхронизации

Хоккей, твоя правда. Не часто с ними работаю.

3
02 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
Ну так ожидать-то объект нужно будет с помощью Wait-функции, а основной поток тормозить нецелесообразно.


Так и не надо тормозить. Проверили и пошли дальше по условию: изменилось или нет состояние оъекта синхронизации.

534
02 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Так и не надо тормозить. Проверили и пошли дальше по условию: изменилось или нет состояние оъекта синхронизации.

И так до тех пор, пока состояние не изменится? Тогда, на мой взгляд, проще использовать сообщения.

3
03 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
И так до тех пор, пока состояние не изменится? Тогда, на мой взгляд, проще использовать сообщения.


Возможно проще, но не лучше, т.к. сообщения находятся в очереди, если очередь заполнится сообщениями, то встанет не только UI, но и бизнес-логика.

534
03 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Возможно проще, но не лучше, т.к. сообщения находятся в очереди, если очередь заполнится сообщениями, то встанет не только UI, но и бизнес-логика.

Не надо всё так усложнять. В данном случае основные расчёты производит уведомляющий процесс, а другой процесс просто подбирает за ним результаты. Я полагаю, что расчёт (хотя бы даже и в среднем) одной порции данных занимает гораздо больше времени, чем вывод её на экран. А если так, то, в принципе, можно сообщения посылать с ожиданием завершения отображения результатов, тогда переполняться ничего не будет (если уж так страшно :)). При использовании глобальных объектов синхронизации точно так же будут ситуации, когда процессы (точнее даже, потоки из обоих процессов) будут выполняться попеременно, ожидая друг друга.
Для несложной задачи имеем несложное решение. Рихтер, например, использовал пользовательские сообщения в качестве одной из составляющих механизма обмена данными между процессами/потоками в очень большом количестве своих примеров, и, при этом, называл их достаточным решением для простых задач из данной области.

3
03 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
Не надо всё так усложнять.


IMHO глобальная синхронизация даже проще :)

Цитата:
Originally posted by HarryAxe
При использовании глобальных объектов синхронизации точно так же будут ситуации, когда процессы (точнее даже, потоки из обоих процессов) будут выполняться попеременно, ожидая друг друга.


Одно дело, когда они ждут конкретного события синхронизации, а другое дело, когда они раскручивают очередь сообщений UI и между прочим еще и получают через эту очередь сообщения синхронизации. Другими словами выставляя объект синхронизации мы уверены, что другой процесс получит этот сигнал, как только обратиться к этому объекту синхронизации. А передавая сигнал синхронизации через очередь оконных сообщений мы ждем пока процесс-получатель раскрутит очередь до этого сообщения, а этого кстати, может так и не произойти, еслу в очередь попадут сообщения с более высоким приоритетом.

Цитата:
Originally posted by HarryAxe
Для несложной задачи имеем несложное решение. Рихтер, например, использовал пользовательские сообщения в качестве одной из составляющих механизма обмена данными между процессами/потоками в очень большом количестве своих примеров, и, при этом, называл их достаточным решением для простых задач из данной области.


В данном случае довольно корявое решение ещё по тому, что имея объект синхронизации мы чередуем владение общим ресурсом, как эстафетной палочкой. Передавая оконное сообщение, чередование становится неоднозначным, а само явление владения неопределенным. Ну и соотв-но начинаются вопросы - кто инициирует передачу и создает глобальный ресурс, кто уничтожает. Одной из проблем возникает неопределенность при завершении одной из программ: сообщение о закрытии окна придет раньше, чем сообщение о доступности ресурса, т.о. приложение завершится, неуведомив другое, что ресурс свободен.

351
03 мая 2006 года
PitxBull
633 / / 22.12.2004
да вообщем то если выбирать между посылкой сообщений и глобальным объектом синхронизации, то последний вариань явно эффективней. Но вот если надо организовать взаимодейтсвие процессов на разных машинах то тут уж помоему лучше использовать COM. По крайней мере вариант с COM покрывает все возможные случаи единым унифициованным образом.
534
03 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Одно дело, когда они ждут конкретного события синхронизации, а другое дело, когда они раскручивают очередь сообщений UI и между прочим еще и получают через эту очередь сообщения синхронизации. Другими словами выставляя объект синхронизации мы уверены, что другой процесс получит этот сигнал, как только обратиться к этому объекту синхронизации. А передавая сигнал синхронизации через очередь оконных сообщений мы ждем пока процесс-получатель раскрутит очередь до этого сообщения, а этого кстати, может так и не произойти, еслу в очередь попадут сообщения с более высоким приоритетом.

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

Цитата:
Originally posted by Green
В данном случае довольно корявое решение ещё по тому, что имея объект синхронизации мы чередуем владение общим ресурсом, как эстафетной палочкой. Передавая оконное сообщение, чередование становится неоднозначным, а само явление владения неопределенным. Ну и соотв-но начинаются вопросы - кто инициирует передачу и создает глобальный ресурс, кто уничтожает. Одной из проблем возникает неопределенность при завершении одной из программ: сообщение о закрытии окна придет раньше, чем сообщение о доступности ресурса, т.о. приложение завершится, неуведомив другое, что ресурс свободен.

Не вижу причин для возникновения подобных проблем. В случае нотификации с помощью сообщений общий ресурс должен создавать/удалять уведомляющий процесс. Если он завершится раньше, чем уведомляемый, то просто отправит перед выходом соответствующее сообщение в синхронном режиме, и никакие данные не потеряются. Если раньше завершится уведомляемый процесс, то SendMessage при обращении к несуществующему окну завершится неудачей и возвратит 0. То есть, достаточно при успешном выводе на экран возвращать в обработчике ненулевое значение, и всё будет в шоколаде. Корявого, на мой взгляд, здесь ничего нет.

3
04 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
Одинаково приятно, поскольку так или иначе уведомляющий процесс будет ждать завершения вывода на экран в другом процессе, который, в свою очередь, будет происходить через механизм сообщений. Так что раскрутка будет и в том, и в другом случае.


Так а зачем ждать окончания вывода на экран?

Цитата:
Originally posted by HarryAxe
Не вижу причин для возникновения подобных проблем. В случае нотификации с помощью сообщений общий ресурс должен создавать/удалять уведомляющий процесс. Если он завершится раньше, чем уведомляемый, то просто отправит перед выходом соответствующее сообщение в синхронном режиме, и никакие данные не потеряются. Если раньше завершится уведомляемый процесс, то SendMessage при обращении к несуществующему окну завершится неудачей и возвратит 0. То есть, достаточно при успешном выводе на экран возвращать в обработчике ненулевое значение, и всё будет в шоколаде. Корявого, на мой взгляд, здесь ничего нет.


1. Как понять, что общий ресурс создан?

2. Кроме того ресурс не может сам ничего создавать, его самого выделяют и пользуют.

P1 <-данные-> Shared <-данные-> P2

3. Как P1 поймет, кому передавать сообщения? FindWindow? Как-то ненадежно...

4. Рассмотрим такую ситуацию: P1 заполнил общий ресурс данными и послал уведомление P2, которое встало в очередь сообщений. Теперь P1 ждет уведомления от P2 об окончании обработки переданных данных. Но в процессе раскрутки очереди сообщений в P2, поступает сообщение WM_CLOSE (WM_DESTROY), которое более приоритетно, чем наше сообщение синхронизации. В результате P2 скоропостижно скончалось, не успев уведомить P1, которое теперь вечно будет ждать сообщения от почившего P2.
Заставить P2 перед смертью уведомлять родных и близких о своей кончине? Не усложняется ли при этом "несложное решение для несложной задачи".
А если P2 скончается в результате несчастного случая? Кто распорядится наследством?

351
04 мая 2006 года
PitxBull
633 / / 22.12.2004
кроме того при использовании глобальных объектов синхронизации возникает неоходимость в их явной защите , иначе этим объектом синхронизации может воспользоваться сторонняя программа-вредитель и таким образом нарушить работу оригинальных программ.
351
04 мая 2006 года
PitxBull
633 / / 22.12.2004
и вообще здается мне что эта задача частный случай паттерна model-view-controller.
534
04 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Так а зачем ждать окончания вывода на экран?


К примеру, SetWindowText() отсылает элементу управления сообщение WM_SETTEXT в синхронном режиме. Иметь в нашем случае две копии данных (одна - защищённая, другая - локальная для процесса и используется для отсылки сообщений элементам управления), на мой взгляд, нерационально.

Цитата:
Originally posted by Green
1. Как понять, что общий ресурс создан?

Если поступило сообщение о возникновении новых данных, то ресурс уже создан (естесственно, если ресурс создан уведомляющим процессом)

Цитата:
Originally posted by Green
2. Кроме того ресурс не может сам ничего создавать, его самого выделяют и пользуют.

Во фразе

Цитата:
В случае нотификации с помощью сообщений общий ресурс должен создавать/удалять уведомляющий процесс.

подлежащим является слово "процесс" (sorry, если выразился неоднозначно)

Цитата:
Originally posted by Green
P1 <-данные-> Shared <-данные-> P2

3. Как P1 поймет, кому передавать сообщения? FindWindow?

Не обязательно. Процесс, выводящий данные на экран, может один раз уведомить о своём присутствии тем или иным способом (например, с помощью тех же сообщений). Я могу задать вопрос из той же серии: предположим, что запущено два процесса, генерирующих нужные нам данные (возможно даже, пользователь случайно тыкнул кнопкой лишний раз). Как, при использовании объектов синхронизации, программа, которая выводит результаты, узнает, какой из процессов ей эти данные предоставил?

Цитата:
Originally posted by Green
4. Рассмотрим такую ситуацию: P1 заполнил общий ресурс данными и послал уведомление P2, которое встало в очередь сообщений. Теперь P1 ждет уведомления от P2 об окончании обработки переданных данных. Но в процессе раскрутки очереди сообщений в P2, поступает сообщение WM_CLOSE (WM_DESTROY), которое более приоритетно, чем наше сообщение синхронизации. В результате P2 скоропостижно скончалось, не успев уведомить P1, которое теперь вечно будет ждать сообщения от почившего P2.
Заставить P2 перед смертью уведомлять родных и близких о своей кончине? Не усложняется ли при этом "несложное решение для несложной задачи".
А если P2 скончается в результате несчастного случая? Кто распорядится наследством?

Опять усложняешь? Взаимный обмен сообщениями в нашем случае необязателен, уведомляющий процесс может отсылать сообщения в синхронном режиме (то есть, с помощью SendMessage). Если ресурс создаётся уведомляющим процессом, то другой процесс обрабатывать его уничтожение не обязан, на его работу это не повлияет (он обращается к разделяемым данным только при обработке соответствующего сообщения). WM_CLOSE не будет обработано до тех пор, пока обработчик нашего сообщения не возвратит управление (естесственно, если на этот момент наше уведомляющее сообщение уже обрабатывается, в противном случае, как я уже говорил, SendMessage вернёт 0).

351
04 мая 2006 года
PitxBull
633 / / 22.12.2004
Цитата:
Originally posted by HarryAxe
Я могу задать вопрос из той же серии: предположим, что запущено два процесса, генерирующих нужные нам данные (возможно даже, пользователь случайно тыкнул кнопкой лишний раз). Как, при использовании объектов синхронизации, программа, которая выводит результаты, узнает, какой из процессов ей эти данные предоставил?


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

534
04 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by PitxBull
если проги генерирующие данные по определению две и это определено архитектурно то можно как миниум использовать два разных объекта синхронизации. случайный же запуск двух прог генерирующих данные должен быть исключен с помощью соответствующих методов. Так как в этом случае архитектурно прога генерериующая данные - одна.

Ну, если каждая программа запущена лишь в одном экземпляре (по определению), то даже FindWindow выглядит не так уж ненадёжно (хотя хорошим механизмом её не назовёшь).

3
04 мая 2006 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by HarryAxe
Я могу задать вопрос из той же серии: предположим, что запущено два процесса, генерирующих нужные нам данные (возможно даже, пользователь случайно тыкнул кнопкой лишний раз). Как, при использовании объектов синхронизации, программа, которая выводит результаты, узнает, какой из процессов ей эти данные предоставил?


Если источник должен быть один, то это обеспечивается все теми же объектами синхронизации. Если - несколько, то здесь нужен либо механизм соответствия, что несложно, либо просто неименованые pipes, только тогда P2 должен быть порожден от P1.

Цитата:
Originally posted by HarryAxe
Взаимный обмен сообщениями в нашем случае необязателен, уведомляющий процесс может отсылать сообщения в синхронном режиме (то есть, с помощью SendMessage).


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

534
04 мая 2006 года
HarryAxe
448 / / 19.01.2006
Цитата:
Originally posted by Green
Т.о. мы получаем жесткую синхронную связь двух процессов: один будет постоянно ждать другого?


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

Цитата:
Originally posted by Green
Здесь нужен механизм соответствия


А можно поподробнее о таком механизме? В чём он будет заключаться?

Цитата:
Originally posted by Green
Либо просто неименованые pipes, только тогда P2 должен быть порожден от P1.

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

15K
05 мая 2006 года
DubAlex
10 / / 26.04.2006
Цитата:
Originally posted by HarryAxe
Ну, тут уже у автора надо спросить, каким образом он запускает каждый из процессов. Если один из них порождает другой, то решение задачи в любом случае упростится.


Нет, первый процесс не порождает второй. Пока у меня вроде бы все получается. Огромное спасибо всем за помощь.

15K
06 мая 2006 года
DubAlex
10 / / 26.04.2006
Спасибо за помощь. Я использую Pipes. Появилась трудность.
Есть следующий код для клиента:

LPTSTR lpszPipename = "\\\\.\\pipe\\kolTelN";
HANDLE hPipe;
WaitNamedPipe(lpszPipename, NMPWAIT_WAIT_FOREVER);
hPipe = CreateFile(lpszPipename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if (hPipe == INVALID_HANDLE_VALUE)
MessageBox(0, "Invalid handle value1", NULL, MB_OK);
DWORD bytesWrt;
unsigned char kolTelN=i+1;
int res = WriteFile( hPipe, &kolTelN, 1, &bytesWrt, NULL );
if(!res)
MessageBox(0, "Can't write to file", NULL, MB_OK);
CloseHandle(hPipe);

Насколько я понял, строка:
WaitNamedPipe(lpszPipename, NMPWAIT_WAIT_FOREVER);
заставляет клиента ждать пока сервер не создаст Pipe с таким именем. Но клиент не ждет а выполняет следующие операции и из-за этого возникают глюки (и переменная hPipe =INVALID_HANDLE_VALUE и res = 0 и т.д.). Как это исправить? Или я плохо разобрался с принципом работы Pipes?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог