Как реализовать описанное ниже межпроцессорное взаимодействие?

Модератор: Модераторы разделов

Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

Друзья! Один процесс должен писать в файл, а другой оттуда читать. На самом деле я не знаю, в файл ли, но, коль скоро в линуксе всё файл, то и я такое слово употреблю. Первый процесс pr1 суть скрипт, работает так: (псевдокод):

Код: Выделить всё

#!/bin/bash

#Тут цикл:

while true
do
	echo "hello" > <какой-то хитрый файл, не понять какой>
done
А второй процесс pr2 работает себе запущенным в консоли (желательно откреплённым) и строчки "hello" обрабатывает как ему нужно. Не одну, не две, не три, а сколько нужно. То есть строчка "hello" попала в <какой-то хитрый файл, не понять какой>, процесс pr2 считал её оттуда и обработал ждёт следующей строчки. Вот это собсно, я реализовать и не могу. Ну а внешне (в консоли это выглядит так):

Shell

$ ./pr2 <тут параметры какие-нибудь если нужо> &
$
./pr2 лучше на С/C++ реализовать.

Если будем говорить о pipe, то вот отсюда пример у меня работать не хочет, Процесс pr2 считывает одну (первую положенную) строчку из <какой-то хитрый файл, не понять какой> и программа завершается, хотя там зачем-то вечный цикл нарисован. Debian 11. Спасибо, кто откликнется.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21000
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение Bizdelnick »

жучара писал(а):
25.11.2022 20:52
Если будем говорить о pipe, то вот отсюда пример у меня работать не хочет, Процесс pr2 считывает одну (первую положенную) строчку из <какой-то хитрый файл, не понять какой> и программа завершается, хотя там зачем-то вечный цикл нарисован. Debian 11. Спасибо, кто откликнется.
Если Вы про mkfifo.c, то там прописано условие завершения, которое абсолютно корректно срабатывает, когда pr1 закрывает файл и следующая попытка чтения возвращает 0.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

Для bash, то довольно просто:
Слушатель:

Код: Выделить всё

#!/bin/bash 

TEMP="/tmp/testfile"
mkfifo $TEMP
exec 3<> $TEMP

while read line
do
	if [[ $line == "ambacaput" ]] ; then
		break
	else
		echo $line
	fi
done <&3
rm /tmp/testfile
А далее все строки что передаются в /tmp/testfile будут обрабатываться в цикле. То же самое можно сделать и через tail -f с циклом.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

Bizdelnick писал:
25.11.2022 21:06
жучара писал(а):
25.11.2022 20:52
Если будем говорить о pipe, то вот отсюда пример у меня работать не хочет, Процесс pr2 считывает одну (первую положенную) строчку из <какой-то хитрый файл, не понять какой> и программа завершается, хотя там зачем-то вечный цикл нарисован. Debian 11. Спасибо, кто откликнется.
Если Вы про mkfifo.c, то там прописано условие завершения, которое абсолютно корректно срабатывает, когда pr1 закрывает файл и следующая попытка чтения возвращает 0.
очень хорошо. У меня вопрос был- как мне мой замысел реализовать?
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

ormorph писал(а):
25.11.2022 21:21
Для bash, то довольно просто:
Слушатель:

Код: Выделить всё

#!/bin/bash 

TEMP="/tmp/testfile"
mkfifo $TEMP
exec 3<> $TEMP

while read line
do
	if [[ $line == "ambacaput" ]] ; then
		break
	else
		echo $line
	fi
done <&3
rm /tmp/testfile
А далее все строки что передаются в /tmp/testfile будут обрабатываться в цикле. То же самое можно сделать и через tail -f с циклом.
нет, у меня слушатель на С/C++ должен быть.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21000
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение Bizdelnick »

жучара писал(а):
26.11.2022 00:50
как мне мой замысел реализовать?
Не знаю, я не умею читать мысли. Вам нужно что-то вроде клиент-серверного взаимодействия? Тогда более логично использовать сокеты. Нужен именно интерфейс через запись в файл? Насколько критично использовать именно FIFO, или, может быть, обычный файл (в котором будет сохраняться всё, в него записанное), больше подойдёт?
Вы, как обычно, рассказываете очень маленький кусочек задачи, недостаточный для того, чтобы найти оптимальное решение.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

Bizdelnick писал:
26.11.2022 01:19
жучара писал(а):
26.11.2022 00:50
как мне мой замысел реализовать?
Не знаю, я не умею читать мысли. Вам нужно что-то вроде клиент-серверного взаимодействия? Тогда более логично использовать сокеты. Нужен именно интерфейс через запись в файл? Насколько критично использовать именно FIFO, или, может быть, обычный файл (в котором будет сохраняться всё, в него записанное), больше подойдёт?
Вы, как обычно, рассказываете очень маленький кусочек задачи, недостаточный для того, чтобы найти оптимальное решение.
более вам знать и не нужно. Требования были такие (повторяюсь уже). Писатель пишет в файл вот так:

Код: Выделить всё

#!/bin/bash

#Тут цикл:

while true
do
	echo "hello" > <какой-то хитрый файл, не понять какой>
done
а читатель читает это всё на C/C++ и обрабатывает. Всё. По-моему. это просто понять. Может быть, недостаточно. Спросите. Подойдёт ли мне простой файл, FIFO, ещё что, я понятия не имею, главное, чтобы вот такой у них был интерфейс. Хотя уже, к примеру сокеты на этой стадии можно отбросить, да ведь? Потому, что там их нужно реализовывать на плюсах, что писатель, что читатель, и там вообще они по-ему обмениваются сообщениями send()/recv(), каким боком тут интерфейс:
echo "hello" > <какой-то хитрый файл, не понять какой>
- я его для кого вообще пишу-то? Но вообще я уже решил. Тем более, что решилось действительно просто. Сперва читатель:
#include <stdio.h>
#include <unistd.h>

int main ()
{
char bf [50];
while (1)
{
fgets (bf, 50, stdin);
printf ("%s\n", bf);
}
return 0;
}
Теперь писатель:

Shell

$ echo hello > /proc/1163891/fd/0
$ echo word > /proc/1163891/fd/0
$
читатель запускаем:

Shell

$ ./a.out
hello
word
...
Такие дела. Кто может сделать лучше, пусть сделает лучше.
Offtopic
gets() отменили, true и false тоже и пожаловаться некому
Последний раз редактировалось жучара 27.11.2022 06:05, всего редактировалось 1 раз.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

жучара писал(а):
26.11.2022 01:44
Кто может сделать лучше, пусть сделает лучше.
И что вам мешало использовать fgets с дескриптором именовангого канала fifo?
Тогда бы pid не нужен был - если имя фиксированное.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

ormorph писал(а):
26.11.2022 07:31
жучара писал(а):
26.11.2022 01:44
Кто может сделать лучше, пусть сделает лучше.
И что вам мешало использовать fgets с дескриптором именовангого канала fifo?
Тогда бы pid не нужен был - если имя фиксированное.
нельзя ли код?
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

жучара писал(а):
26.11.2022 15:01
нельзя ли код?

Код: Выделить всё

#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE        50

int main (int argc, char ** argv) {
    FILE *fp;
    char buf[BUFSIZE];

    if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
        perror("mkfifo");
        return 1;
    }
    fp = fopen(NAMEDPIPE_NAME, "r");
    while (1)
    {
    	fgets (buf, BUFSIZE, fp);
    	printf ("%s\n", buf);
    }
}
Что то типа этого. Не проверял, но оно должно работать. Тут просто файл открывается как поток (fopen) , раз у вас с stdin работает, то и тут должно работать...
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

ormorph писал(а):
26.11.2022 16:03
жучара писал(а):
26.11.2022 15:01
нельзя ли код?

Код: Выделить всё

#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE        50

int main (int argc, char ** argv) {
    FILE *fp;
    char buf[BUFSIZE];

    if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
        perror("mkfifo");
        return 1;
    }
    fp = fopen(NAMEDPIPE_NAME, "r");
    while (1)
    {
    	fgets (buf, BUFSIZE, fp);
    	printf ("%s\n", buf);
    }
}
Что-то типа этого. Не проверял, но оно должно работать. Тут просто файл открывается как поток (fopen) , раз у вас с stdin работает, то и тут должно работать...
не проверял, но если этот код как отсюда, то он не работает. Я об этом в первом сообщении писал
https://habr.com/ru/post/122108/#part_namedpipe
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

жучара писал(а):
26.11.2022 19:01
не проверял, но если этот код как отсюда, то он не работает. Я об этом в первом сообщении писал
https://habr.com/ru/post/122108/#part_namedpipe
Нет, от туда взята шапка(создание fifo файла), остальное отличается. Там используется open а тут fopen, они возвращают разный тип. Позже проверю у себя на компе, но думаю что всё заработает.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

Проверил, в принципе рабочий но не совсем, права открытия немного изменил, стало работать как надо:

Код: Выделить всё

#include <sys/stat.h>
#include <string.h>
#include <stdio.h>

#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE        50

int main (int argc, char ** argv) {
    FILE *fp;
    char buf[BUFSIZE];

    if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
        perror("mkfifo");
        return 1;
    }
    fp = fopen(NAMEDPIPE_NAME, "r+");
    while (1)
    {
    	fgets (buf, BUFSIZE, fp);
	if ( ! strcmp( buf, "ambacaput\n") ) {
		remove(NAMEDPIPE_NAME);
		return 0;
	}
    	printf ("%s", buf);
    }
}
Если передать в файл fifo - ambacaput, то файл удаляется а программа завершается.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 1035
ОС: астралинукс

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение жучара »

ormorph писал(а):
26.11.2022 21:15
Проверил, в принципе рабочий но не совсем, права открытия немного изменил, стало работать как надо:

Код: Выделить всё

#include <sys/stat.h>
#include <string.h>
#include <stdio.h>

#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE        50

int main (int argc, char ** argv) {
    FILE *fp;
    char buf[BUFSIZE];

    if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
        perror("mkfifo");
        return 1;
    }
    fp = fopen(NAMEDPIPE_NAME, "r+");
    while (1)
    {
    	fgets (buf, BUFSIZE, fp);
	if ( ! strcmp( buf, "ambacaput\n") ) {
		remove(NAMEDPIPE_NAME);
		return 0;
	}
    	printf ("%s", buf);
    }
}
Если передать в файл fifo - ambacaput, то файл удаляется а программа завершается.
Спасибо, это как раз то, что нужно. По ссылке пример такой, что он считывает строку ровно один раз и всё, это ерунда какая-то. Я пробовал разобраться в чём дело, сделал вывод, что дело в разных функциях, которые используются, у вас используется функция fgets, а там read. К сожалению, дальше продвинуться не мог. Почему если read, то работать не будет в вечном цикле, чёрт его знает.

...Мой код, к сожалению, тоже не совсем хорошо работает. Например, это работать не будет:

Код: Выделить всё

#include <stdio.h>
#include <unistd.h>

int main ()
{
char bf [50];
while (1)
{
	fgets (bf, 50, stdin);
	printf ("%s\n", bf);
	printf ("Hello, word!\n");
	
}
return 0;
}
Так, если данные подавать в соседней консоли так:
echo yyy > /proc/1477871/fd/0
то "Hello, word!" выводиться не будет.

...Но самое большое удивление, это что вот эти вот stdin, stdout и stderr это на самом деле одно и то же.

Shell

$ ls -l /proc/1477895/fd/*
lrwx------ 1 userd userd 64 ноя 27 08:15 /proc/1477895/fd/0 -> /dev/pts/1
lrwx------ 1 userd userd 64 ноя 27 08:15 /proc/1477895/fd/1 -> /dev/pts/1
lrwx------ 1 userd userd 64 ноя 27 08:15 /proc/1477895/fd/2 -> /dev/pts/1
$
Это выше моего понимания. Но это уже совсем другая история.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

жучара писал(а):
27.11.2022 06:19
Спасибо, это как раз то, что нужно. По ссылке пример такой, что он считывает строку ровно один раз и всё, это ерунда какая-то.
Это можно изменить в функции open - O_RDONLY заменить на O_RDWR, тогда будет бесконечно считывать, но там функция read не может считывать построчно, по этому под ваши нужды не подходит.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21000
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение Bizdelnick »

Забавно. ormorph открывает FIFO не только для чтения, а для чтения и записи, из-за чего закрытие его отправляющей стороной не приводит к получению EOF. Называть это работой «как надо» несколько странно. В лучшем случае костыль.
P. S. Проверять на ошибки значения, возвращаемые fopen и fgets, в любом случае нужно.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

Bizdelnick писал:
28.11.2022 01:21
P. S. Проверять на ошибки значения, возвращаемые fopen и fgets, в любом случае нужно.
Это само собою, но я и не писал приложение, а только пример.
Bizdelnick писал:
28.11.2022 01:21
В лучшем случае костыль.
Если это костыль, то зачем его описывать в документации. Как раз с fifo так и надо, иначе fgets не переходит к следующей строке, а всё время крутится на первой(это с fopen). Т.е. буфер fifo не очищается и не работает как поток.
Хотя это тоже работает норм:

Код: Выделить всё

#include <sys/stat.h>
#include <string.h>
#include <stdio.h>

#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE        50

int main (int argc, char ** argv) {
	FILE *fp;
	char buf[BUFSIZE];

	if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
		perror("mkfifo");
		return 1;
	}

	fp = fopen(NAMEDPIPE_NAME, "r");
	while (1)
	{
		if ( ! fgets (buf, BUFSIZE, fp) ) {
			fclose(fp);
			fp = fopen(NAMEDPIPE_NAME, "r");
			continue;
		}

		if ( ! strcmp( buf, "ambacaput\n") ) {
			fclose(fp);
			remove(NAMEDPIPE_NAME);
			return 0;
		}
		printf ("%s", buf);
	}
}
Но в любом случае это то же самое. Ну и демон обычно убивается, он и предназначен, что бы постоянно слушать.Проверять fopen лень, пусть так и будет.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21000
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение Bizdelnick »

ormorph писал(а):
28.11.2022 01:39
Если это костыль, то зачем его описывать в документации.
А где он описан? Не видел такого.
ormorph писал(а):
28.11.2022 01:39
Как раз с fifo так и надо, иначе fgets не переходит к следующей строке, а всё время крутится на первой(это с fopen). Т.е. буфер fifo не очищается и не работает как поток.
Нигде он не крутится. Это Ваш цикл крутится, потому что Вы не прописали условие выхода при получении EOF.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

Bizdelnick писал:
28.11.2022 11:22
Это Ваш цикл крутится, потому что Вы не прописали условие выхода при получении EOF.
Так по условию ему и не надо выходить после переданной первой же строки и закрытия соединения. По этому если выход по EOF, то цикл отработает только один раз, а далее если будут передаваться новые команды уже работать не будет, так как выйдет по EOF.
Ему просто нужно было передавать в реальном времени строки, и чтобы программа в зависимости от значений выполняла.определённые действия.
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21000
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение Bizdelnick »

ormorph писал(а):
28.11.2022 11:35
Так по условию ему и не надо выходить после переданной первой же строки и закрытия соединения. По этому если выход по EOF, то цикл отработает только один раз, а далее если будут передаваться новые команды уже работать не будет, так как выйдет по EOF.
Отлично, Вы уже наполовину поняли, что происходит. Осталось только понять, что после получения EOF ничего считать нельзя по определению, поэтому fgets никак не меняет содержимое буфера, а вовсе не «крутится на первой строке». И уж точно из этого не следует, что «буфер fifo не очищается».
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2913
ОС: Gentoo

Re: Как реализовать описанное ниже межпроцессорное взаимодействие?

Сообщение ormorph »

Bizdelnick писал:
28.11.2022 11:41
Осталось только понять, что после получения EOF ничего считать нельзя по определению, поэтому fgets никак не меняет содержимое буфера, а вовсе не «крутится на первой строке».
Да как бы догадался, я же не с бухты барахты написал последний вариант с EOF, но перезапуском считывания.
Добавлено (11:49):
Bizdelnick писал:
28.11.2022 11:41
И уж точно из этого не следует, что «буфер fifo не очищается».
Буфер fifo очищается после закрытия fclose. Т.е. не обязательно достигать EOF.
Спасибо сказали: