Передать произвольные данные в уже запущенную программу. (Нужна коллективная мысль.)
Модератор: Модераторы разделов
-
Zeus
- Сообщения: 694
Передать произвольные данные в уже запущенную программу.
Есть программа, написанная мною (т.е. я о ней всё знаю и, в принципе, могу добавить какую угодно функциональность), но запущенная в системе когда-то и кем-то. Я могу узнать её PID.
Есть потребность передать ей, ну допустим, символьную строку или число (хотя число тоже можно строкой передать).
Как это правильнее, логичнее, разумнее, переносимее (продолжить по необходимости) сделать?
Совсем замечательно - если это можно из bash'а сделать.
Т.е. не писать отдельную программу, а какой-нибудь echo или ещё что-нибудь подобное использовать.
Есть потребность передать ей, ну допустим, символьную строку или число (хотя число тоже можно строкой передать).
Как это правильнее, логичнее, разумнее, переносимее (продолжить по необходимости) сделать?
Совсем замечательно - если это можно из bash'а сделать.
Т.е. не писать отдельную программу, а какой-нибудь echo или ещё что-нибудь подобное использовать.
-
Omnifarious
- Сообщения: 119
- ОС: Gentoo x86_64
Re: Передать произвольные данные в уже запущенную программу.
В свое время мы писали программку, которая передавала файлы с помощью сигналов SIGUSR1 и SIGUSR2. В принципе так можно передавать любые двоичные данные, лишь бы клиентская программа их принимала.
There is more than one way to do it
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Omnifarious писал(а): ↑24.03.2006 10:26В свое время мы писали программку, которая передавала файлы с помощью сигналов SIGUSR1 и SIGUSR2. В принципе так можно передавать любые двоичные данные, лишь бы клиентская программа их принимала.
А как можно с помощью сигнала (события т.е.?) передать файл?
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
Zeus писал(а): ↑24.03.2006 10:18Есть программа, написанная мною (т.е. я о ней всё знаю и, в принципе, могу добавить какую угодно функциональность), но запущенная в системе когда-то и кем-то. Я могу узнать её PID.
Есть потребность передать ей, ну допустим, символьную строку или число (хотя число тоже можно строкой передать).
Как это правильнее, логичнее, разумнее, переносимее (продолжить по необходимости) сделать?
Совсем замечательно - если это можно из bash'а сделать.
Т.е. не писать отдельную программу, а какой-нибудь echo или ещё что-нибудь подобное использовать.
Google -> Interprocess Communications
Моя подпись сильно длинная :)
-
JaGoTerr
- Сообщения: 380
Re: Передать произвольные данные в уже запущенную программу.
$ mkfifo /tmp/my_fifo_file
$ echo "what u want" > /tmp/my_fifo_file
Ну а уж читать fifo-файл в программе больщого ума не надо.
man fifo, короче говоря.
$ echo "what u want" > /tmp/my_fifo_file
Ну а уж читать fifo-файл в программе больщого ума не надо.
man fifo, короче говоря.
-
Omnifarious
- Сообщения: 119
- ОС: Gentoo x86_64
Re: Передать произвольные данные в уже запущенную программу.
По битам. Пришел SIGUSR1 - значит 0, SIGUSR2 - 1. Так собираешь потихоньку байтики - получается файл. Главное про синхронизацию передающей и принимающей стророны не забывать. Работает очень медленно
P.S. Но сокеты конечно проще и логичнее использовать.
There is more than one way to do it
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
Omnifarious писал(а): ↑24.03.2006 11:13По битам. Пришел SIGUSR1 - значит 0, SIGUSR2 - 1. Так собираешь потихоньку байтики - получается файл. Главное про синхронизацию передающей и принимающей стророны не забывать. Работает очень медленно, но по мелочам(строчку там передать) - не напрягает.
P.S. Но сокеты конечно проще и логичнее использовать.
Ну вы даете! Пишите еще
З.Ы. Я даже из своего предыдущего поста убрал, что никак передать через сигналы файл нельзя
Моя подпись сильно длинная :)
-
Omnifarious
- Сообщения: 119
- ОС: Gentoo x86_64
Re: Передать произвольные данные в уже запущенную программу.
Это была задача преподавателя по информатике. Любил он нетривиальные решения
There is more than one way to do it
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
("(Prentice Hall 2003) - Unix Systems Programming. Communication @ Concurrency, and Threads") писал(а):The usefulness of signal handlers is limited by the inability to pass values to them. This capability has been added to the POSIX:RTS and POSIX:XSI Extensions, which can use the alternative sa_sigaction field of the struct sigaction structure to specify a handler.
Во как! Таки можно с сигналами данные передавать! ( при указанных выше условиях ессесно
З.Ы. Если кому интересно приведу более детальное описание как это сделать, но на инглише! Переводить влом
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Ну что ж, мнение народа понятно
Спасибо всем.
Нихрена себе изврат какой!

Спасибо всем.
Omnifarious писал(а): ↑24.03.2006 11:13
По битам. Пришел SIGUSR1 - значит 0, SIGUSR2 - 1. Так собираешь потихоньку байтики - получается файл. Главное про синхронизацию передающей и принимающей стророны не забывать. Работает очень медленно, но по мелочам(строчку там передать) - не напрягает.
P.S. Но сокеты конечно проще и логичнее использовать.
Нихрена себе изврат какой!
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Спасибо за наводку
Но в процессе экспериментов появилась ещё проблема:
1. Сделал я fifo
2. Открыл её на чтение в программе.
3. В бесконечном цикле читаю файл - поток заблокировался на read.
3. Кинул из консоли туда сообщение echo'ом.
4. Оно прочиталось.
5. И на следующей итерации цикла read уже не блокируется, а бесконечно выдаёт одну и ту же строку - ту самую, первую которую я ему кинул.
Пробовал std::ifstream использовать - тоже блокируется только один раз, а потом - одно и то же выдаёт.
Пробовал select - тоже самое. Один раз блокирует, а потом постоянно возвращает что есть дескрипторы для чтения.
В книге (не помню название - довольно детская какая-то) сказано, что ядро заблокирует поток при ОТКРЫТИИ fifo на чтение, пока его кто-то не откроет на запись. Ну а вообще - типа работайте как с обычным файлом.
А вот у меня при ОТКРЫТИИ ничего не блокируется, блокируется при чтении данных.
Но вот дальше - работать "как с обычным файлом" что-то не получается.
-
flook
- Сообщения: 585
- Статус: Просто flook
Re: Передать произвольные данные в уже запущенную программу.
Zeus писал(а): ↑29.03.2006 11:471. Сделал я fifo
2. Открыл её на чтение в программе.
3. В бесконечном цикле читаю файл - поток заблокировался на read.
3. Кинул из консоли туда сообщение echo'ом.
4. Оно прочиталось.
5. И на следующей итерации цикла read уже не блокируется, а бесконечно выдаёт одну и ту же строку - ту самую, первую которую я ему кинул.
сорс в студию.
$ mkfifo x
$ tail -f x
в другом терминале
$ echo 1 > x
$ echo 2 > x
$ echo 3 > x
все прекрасно пашет. наверняка ошибка в программе.
В каждом из нас спит гений... и с каждым днем все крепче...
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
flook писал(а): ↑29.03.2006 14:52Zeus писал(а): ↑29.03.2006 11:47
1. Сделал я fifo
2. Открыл её на чтение в программе.
3. В бесконечном цикле читаю файл - поток заблокировался на read.
3. Кинул из консоли туда сообщение echo'ом.
4. Оно прочиталось.
5. И на следующей итерации цикла read уже не блокируется, а бесконечно выдаёт одну и ту же строку - ту самую, первую которую я ему кинул.
сорс в студию.
$ mkfifo x
$ tail -f x
в другом терминале
$ echo 1 > x
$ echo 2 > x
$ echo 3 > x
все прекрасно пашет. наверняка ошибка в программе.
Исходник - дома. Позже выложу.
bash'евский пример из той же книжки - тоже работает так как ожидалось.
А вот мой C'шный код - не хочет.
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Код такой:
Код: Выделить всё
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <fstream>
#define FOREVER while (1)
//#define FOREVER
//#define READ_C
#define STREAM_CPP
int
main ()
{
#ifdef READ_C
int fd;
fd = open ("fifo", O_RDONLY);
char buf[100];
FOREVER
{
memset (buf,0,100);
read (fd, buf, 100);
std::cout << "buf = [" << buf << "]" << std::endl;
}
#endif
#ifdef STREAM_CPP
std::ifstream fifo ("fifo");
std::string str;
FOREVER
{
str = "";
fifo >> str;
std::cout << "str=[" << str << "]" << std::endl;
}
#endif
return 0;
};Компилю просто: g++ temp.cpp
Если не "обнулять" buf и str, то в следующей итерации цикла их значение равно предыдущему.
Т.е. получается read и операция чтения из потока их не изменяют, сразу возвращая управление.
-
flook
- Сообщения: 585
- Статус: Просто flook
Re: Передать произвольные данные в уже запущенную программу.
1. А ошибки проверять?
2. Когда делается echo 1 > fifo то программа видит следующее:
1. блокируется на open пока echo не сделает open
2. read - видит 1
3. read - EOF, так как echo закрывает файл - после этого всегда будет read возвращать 0.
3. Учите матчасть
2. Когда делается echo 1 > fifo то программа видит следующее:
1. блокируется на open пока echo не сделает open
2. read - видит 1
3. read - EOF, так как echo закрывает файл - после этого всегда будет read возвращать 0.
3. Учите матчасть
В каждом из нас спит гений... и с каждым днем все крепче...
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Ну так, думал тестовый пример - чего там проверять-то?
2. Когда делается echo 1 > fifo то программа видит следующее:
1. блокируется на open пока echo не сделает open
Вот сейчас поправил "эксперимент" - действительно он на open'е блокируется (и на конструкторе ifstream), а не на read, как мне раньше казалось
2. read - видит 1
Не 1, а число реально полученных байт. Но это не важно.
3. read - EOF, так как echo закрывает файл - после этого всегда будет read возвращать 0.
Для EOF вроде отдельная функция есть, но это тоже не важно.
Вот эта непонятная зависимость - что ТАМ закрывают файл, а у меня тут EOF - вот к этому я не был готов.
3. Учите матчасть
Учим. Только не нашёл нормального объяснения работе с fifo в дистрибуте.
А к Инету в тот момент доступ не имел.
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
int fd;
int dummy;
fd = open ("/home/andreyp/fifo", O_RDONLY );
dummy = open ("/home/andreyp/fifo", O_WRONLY );
fifo открой еще и на запись, и будет тебе сЧастЯ... Зачем? flook уже сказал - учите мат часть
З.Ы. А за FOREVER спасибо - плакалЪ
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Спасибо, попробую.
Еще можно, наверное, просто открытие очереди на чтение внести в цикл?
З.Ы. А за FOREVER спасибо - плакалЪ
Пожалуйста. Я думал это известная тема
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
Можно и так, только закрытие туда же внеси. Но это, что называется "через Ж"
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Спасибо.
Правда в потоковой версии добавление std::ofstream не помогло.
Как, впрочем, и открытие очереди на чтение.
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
Опять же - код в студию...
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Да, в общем-то, дополнения небольшие:
Код: Выделить всё
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <fstream>
#define FOREVER while (1)
//#define FOREVER
#define READ_C
//#define STREAM_CPP
int
main ()
{
#ifdef READ_C
int fd, fd1;
fd = open ("fifo", O_RDONLY);
fd1 = open ("fifo", O_WRONLY);
std::cout << "Начинаем" << std::endl;
char buf[100];
int rd;
FOREVER
{
memset (buf,0,100);
rd = read (fd, buf, 100);
std::cout << "buf = [" << buf << "] rd=" << rd << std::endl;
}
close (fd);
close (fd1);
#endif
#ifdef STREAM_CPP
std::ifstream fifo ("fifo");
int fd1 = open ("fifo", O_WRONLY);
std::cout << "Начинаем" << std::endl;
std::string str;
FOREVER
{
std::cout << "Продолжаем" << std::endl;
str = "";
fifo >> str;
std::cout << "str=[" << str << "]" << std::endl;
}
close (fd1);
#endif
return 0;
};Ну или в версии STREAM_CPP вместо открытия файла для записи используется
Код: Выделить всё
std::ofstream fifo1 ("fifo");В обоих случах поток выполнения блокируется на fifo >> str;
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
И это правильно! Блокируется и ждет данные. А тебе что нужно?
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
ifstream fifo ("/home/andreyp/fifo");
ofstream ofifi ( "/home/andreyp/fifo" );
string str;
FOREVER
{
str = "";
fifo >> str;
std::cout << "str=[" << str << "]" << std::endl;
}
Вот так работает?
Моя подпись сильно длинная :)
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
-
t.t
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Передать произвольные данные в уже запущенную программу.
А фигли? И в книжках такие примеры есть; там, где я видел, правда, было for(;;), но разницы-то?(d_Sun @ Mar 30 2006, в 10:05) писал(а):З.Ы. А за FOREVER спасибо - плакалЪ
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
Гарыныч
- Сообщения: 202
- ОС: Gentoo
Re: Передать произвольные данные в уже запущенную программу.
А если взять dbus?
-
Zeus
- Сообщения: 694
Re: Передать произвольные данные в уже запущенную программу.
Zeus писал(а): ↑30.03.2006 18:09
Неа![]()
Продолжаем в аське.
Если будут результаты - выкладываем.
Попробовал без ofstream'а перенести ifstream в тело цикла.
Заработало.
Оставил на ночь echo-цикл.
На 206тысячах передачи сообщений через fifo скрипт упал (написал "Broken pipe"), а С++ прога заблокировалась.
А это что?
-
d_Sun
- Сообщения: 291
Re: Передать произвольные данные в уже запущенную программу.
Так может все условные операторы всякой [ CENSORED ] позаменяем? Где-то гулял по нету язык программирования ПРЕВЕД... Видели?
З.Ы. Я б за такие FOREVы...
Zeus - забей на плюсы
Попробовал без ofstream'а перенести ifstream в тело цикла.
Заработало.
Оставил на ночь echo-цикл.
ни к чему хорошему не приведут. Работай на низком уровне. Ну или оберни в класс эти фифо... ( но опять же пользуй open/read... etc )
Моя подпись сильно длинная :)