Взаимодействие процессов -- как сделать?
От: volk  
Дата: 23.08.01 15:48
Оценка:
Здравствуйте!
Имеется следующая задачка. Запускается до дюжины консольных приложений. Они должны обмениваться между собой данными, но не абы как, а по следующим правилам:
отправляющий процесс вызывает некую процедуру Send, передает ей указатель на массив данных, размер массива и ID процесса-получателя;
принимающий процесс вызывает процедуру Recv, передает ей указатель на буфер, в котором будут сохраняться данные, их размер и ID процесса-отправителя
Сложность состоит в том, что процедура Send не должна дожидаться, пока данные отправятся и будут приняты, а возвращать управление сразу. Так же и Recv только добавляет запрос на получение данных, но не дожидается, пока буфер приема будет заполнен. Кроме того, вовсе не обязательно, что сначала будет вызван Send, а потом Recv. Порядок вызова этих процедур может быть совершенно произвольным.

Буду очень благодарен, если кто-нибудь подскажет, при помощи каких механизмов Windows 95/98 можно организовать такое взаимодействие.
Тот, кто желает, но не делает, распространяет чуму.
Re: Взаимодействие процессов -- как сделать?
От: IT Россия linq2db.com
Дата: 23.08.01 18:23
Оценка:
V> Буду очень благодарен, если кто-нибудь подскажет, при помощи каких механизмов Windows 95/98 можно организовать такое взаимодействие.

При помощи таких же как и в DOS ;) — ручками.
Можно по старинке сохранять посылаемые сообщения в файлы (для каждого процесса в отдельный), и делать это используя блокировку. Но более современно, наверное, будет использовать мапинг и объекты сихронизации.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Взаимодействие процессов -- как сделать?
От: Willi  
Дата: 24.08.01 06:50
Оценка:
Здравствуйте volk, вы писали:

V> Буду очень благодарен, если кто-нибудь подскажет, при помощи каких механизмов Windows 95/98 можно организовать такое взаимодействие.


Если я правильно понял задачу.

Алгоритм реализации взаимодействия полностью ложится на тебя.
А средства для реализации межпроцессного обмена данными есть разные.

— сообщения (WM_COPYDATA в частности)
— разделяемая память (см. CreateFileMapping с передачей INVALID_HANDLE_VALUE в качестве hFile)
— поименованные каналы (NamedPipes)
— DCOM
\/\/i||i
Re[2]: Взаимодействие процессов -- как сделать?
От: ndemia Россия http://ndemia.com
Дата: 24.08.01 15:29
Оценка:
Здравствуйте Willi, вы писали:

W>- сообщения (WM_COPYDATA в частности)

W>- разделяемая память (см. CreateFileMapping с передачей INVALID_HANDLE_VALUE в качестве hFile)
W>- поименованные каналы (NamedPipes)
W>- DCOM

Только замечание: поименованные каналы (они же трубы, они же пайпы, они же пипки :-) ) в Win95/98 не поддерживаются, поддерживаются безымянные (анонимные).
Re: Взаимодействие процессов -- как сделать?
От: volk  
Дата: 27.08.01 16:55
Оценка:
От автора вопроса.

Большое спасибо за внимание к вопросу. Я последовал советам и попытался применить все перечисленное. Но увы ...

1) Файлы, проецируемые в память использовать придется. Но представьте такую ситуацию: процесс выполняет Recv, а соответсвующий Send в другом процессе не выполнен. Тогда, по-видимому, процесс-приемник создает проецируемый файл (можно это так назвать?) с заранее известным именем. Потом процесс-отправитель выполняет, наконец, Send, открывает тот же проецируемый файл и что-то в него пишет. А как теперь перекинуть данные из общего файла в буфер процесса-приемника? Приемник этим заниматься не может, поскольку занят выполнением своей задачи, а других функций взаимодействия, кроме Recv, в нем нет (по условию). Должен найтись кто-то третий, имеющий доступ в адресное пространство приемника. Этот третий и должен переписать данные в буфер приемника.
Но кто этот "третий" и как такое реализовать?

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

3) Сообщений дожидаться не надо, но их нужно принимать и обрабатывать. А для этого в программе (программах) опять же должны иметься какие-то еще процедуры кроме этих самых Send и Recv. Но их там быть не может по условию.

По скудости ума своего я так и не понял, что такое mailslot. Может, это то, что мне нужно?

Да, забыл добавить. Все это должно использоваться только для отладки, поэтому скорость выполнения и объем "пожираемых" ресурсов несущественнен.
Тот, кто желает, но не делает, распространяет чуму.
Re[2]: Взаимодействие процессов -- как сделать?
От: ndemia Россия http://ndemia.com
Дата: 28.08.01 01:44
Оценка:
Здравствуйте volk, вы писали:


V>1) Файлы, проецируемые в память использовать придется. Но представьте такую ситуацию: процесс выполняет Recv, а соответсвующий Send в другом процессе не выполнен. Тогда, по-видимому, процесс-приемник создает проецируемый файл (можно это так назвать?) с заранее известным именем. Потом процесс-отправитель выполняет, наконец, Send, открывает тот же проецируемый файл и что-то в него пишет. А как теперь перекинуть данные из общего файла в буфер процесса-приемника? Приемник этим заниматься не может, поскольку занят выполнением своей задачи, а других функций взаимодействия, кроме Recv, в нем нет (по условию). Должен найтись кто-то третий, имеющий доступ в адресное пространство приемника. Этот третий и должен переписать данные в буфер приемника.

V> Но кто этот "третий" и как такое реализовать?


Этот третий — Windows. Не надо Вам никаких буферов, проецируемый файл — это уже есть память (см. CreateFileMapping). Про когерентность (coherence) посмотрите. Думайте о проекции как об общем блоке памяти, только в разных процессах он может быть в разных адресах, но содержимое будет одинаковым. Не забывайте, что, как и любая общая память, заполняется он асинхронно от чтения, поэтому либо нужна синхронизация, либо данные должны быть самосинхронизирующиеся — то есть из содержимого либо должно быть понятно, что оно дописалось, либо это должно быть неважно (например, просмтаривается просто текущее состояние массива).
Re: Взаимодействие процессов -- как сделать?
От: TSS Россия http://www.sdl.ru
Дата: 30.08.01 07:33
Оценка:
Здравствуйте volk, вы писали:

V> Имеется следующая задачка. Запускается до дюжины консольных приложений. Они должны обмениваться между собой данными, но не абы как, а по следующим правилам:

V> отправляющий процесс вызывает некую процедуру Send, передает ей указатель на массив данных, размер массива и ID процесса-получателя;
V> принимающий процесс вызывает процедуру Recv, передает ей указатель на буфер, в котором будут сохраняться данные, их размер и ID процесса-отправителя
V> Сложность состоит в том, что процедура Send не должна дожидаться, пока данные отправятся и будут приняты, а возвращать управление сразу. Так же и Recv только добавляет запрос на получение данных, но не дожидается, пока буфер приема будет заполнен. Кроме того, вовсе не обязательно, что сначала будет вызван Send, а потом Recv. Порядок вызова этих процедур может быть совершенно произвольным.

V> Буду очень благодарен, если кто-нибудь подскажет, при помощи каких механизмов Windows 95/98 можно организовать такое взаимодействие.


Я так понимаю, сам механизм обмена данными основан на принципе "поточноти" (streaming).

Самый простой на мой взгляд способ -- это механизм сокетов. Работает просто и со вкусом, а если пользовать Windows Sockets 2, то ещё и асинхронно.
Т.е. идея состоит в том, чтобы написать ма-а-асенький сервак (a-la echo service). Send & Recv уже есть...

Можно спокойно использовать WM_COPYDATA вкупе с DDE, только юзать не SendMessage, а PostMessage
А вот при использоваении shared-memory или FileMapping, можно поиметь кучу геморроя...

Да, кстати, всегда остается возможность попользовать ReadProcessMemory() && WriteProcessMemory(), но у меня складывается впечатление, то применение данных фишек будет просто нерименимо.

Signed, [TSS] /SLC/
Signed, [TSS] /SDL/
Re[2]: Взаимодействие процессов -- как сделать?
От: bakulev  
Дата: 22.06.04 23:41
Оценка:
Здравствуйте, TSS, Вы писали:

TSS>Самый простой на мой взгляд способ -- это механизм сокетов. Работает просто и со вкусом, а если пользовать

TSS>Windows Sockets 2, то ещё и асинхронно.
Да и в первых сокетах есть не блокируемый режим.
TSS>Т.е. идея состоит в том, чтобы написать ма-а-асенький сервак (a-la echo service). Send & Recv уже есть...
А если посылать по UDP то и соединения не нужно устанавливать. И сервак не нужно писать, просто каждый процесс будет по своему UDP порту делать Recv своих сообщений и на порту нужного процесса посыдать Send.
при этом никаких бокировок не будет, как послал, так и освободился. А роль буфера будет операционка выполять со своим стеком TCP/IP.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.