LINUX.ORG.RU

Именованные каналы в Linux . Передача данных между процессами


1

2

Прошу помощи с именованными каналами . Нужно передать данные от 1-го процесса в 2-ой . В 1-ом процессе вводятся данные , а во 2-ом они должны выводится .

Вот 2 файла :

Первый файл :


#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
 
using namespace std;
 
int main(int argc, const char * argv[])
{
    unlink("chanelfirst");  //удалить имя , если оно уже есть */
    char msg[255];    //для сообщения
    int err = mknod("chanelfirst",S_IFIFO|0x1b6,0);  //создать канал
    if(err == 0 ) cout <<" chanelfirst created " << endl;
    int pin;
    cout<<" You are in 1 , enter your msg  : "<<endl;
    cin>>msg;    //введение сообщения
   pin = open("chanelfirst",O_WRONLY | O_NDELAY);  //открыть канал
   write(pin, msg, 255);    //записать в канал
   close(pin);                //закрыть канал
   unlink("chanelfirst");    //удалить имя */
    return 0;
}

Второй файл :


#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
 
using namespace std;
 
int main(int argc, const char * argv[])
{   
    char msg[255];   //сообщение
  
    int pinF = open("chanelfirst",O_RDONLY);   //открытие канала
        read(pinF,msg,sizeof(msg));
        cout<<"2 : msg is coming from 1 is: "<<msg<<endl;
    return 0;
}

Ничего не получается вывести во втором процессе , хотя и ввожу данные в первом .

В чём может быть ошибка ? Что я не так делаю ? Подскажите , пожалуйста . Очень надеюсь на Вашу помощь . Заранее спасибо !



Последнее исправление: NNN7 (всего исправлений: 5)

Ответ на: комментарий от MKuznetsov

Если убрать unlink() , то у меня 2-ой процесс вообще ничего не выдаёт

NNN7
() автор топика
Ответ на: комментарий от MKuznetsov

Проверил открытие канала в первом файле :

if(pin == -1 ) cout << " error open" ;

Всё-таки выдаёт ошибку.

Что делать , даже не знаю. Почему не может открыть канал для записи ?

NNN7
() автор топика

fifo сначала нужно открыть на чтение и только потом на запись, у тебя всё наоборот.

mashina ★★★★★
()
Ответ на: комментарий от NNN7

$ man 2 open

If O_NDELAY or O_NONBLOCK is set: An open for reading-only will return without delay; an open for writing-only will return an error if no process currently has the file open for reading.

anonymous
()
Ответ на: комментарий от mashina

Всё равно не понимаю. Поменял в первом файле атрибуты :

pin = open("chanelfirst",O_RDONLY);  //открыть канал

при запуске 1-го файла ошибку не выдаёт , но процесс не останавливается и всё , приходится аварийно его завершать .

И не понимаю, почему в 1-ом файле нужно открывать канал на чтение , если мы в него записываем информацию.

Я думал так , что в 1-ом - для записи , во 2-ом для чтения с канала

NNN7
() автор топика
Ответ на: комментарий от NNN7

И не понимаю, почему в 1-ом файле нужно открывать канал на чтение , если мы в него записываем информацию.

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

mashina ★★★★★
()
Ответ на: комментарий от mashina

Я уже вообще запутался -_-

2-ой файл ( который читает )

int main(int argc, const char * argv[])
{   
    char msg[255];   //сообщение
    int err = mknod("chanelfirst",S_IFIFO|0x1b6,0);  //создать канал
    if(err == 0 ) cout <<" chanelfirst created " << endl;
    int pinF = open("chanelfirst",O_RDONLY);   //открытие канала
        read(pinF,msg,sizeof(msg));
        cout<<"2 : msg is coming from 1 is: "<<msg<<endl;
    return 0;
}

таким должен быть ?

NNN7
() автор топика
Ответ на: комментарий от NNN7

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

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

mashina ★★★★★
()
Ответ на: комментарий от mashina

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

NNN7
() автор топика
Ответ на: комментарий от NNN7

Может сутра лучше разбираться с такими вещами? :)

Для начала упрости свой тест. Выброси создание/удаление FIFO из программ вообще. Создай этот файл из шелла командой mkfifo и не удаляй. Запусти обе модифицированные программы программы и посмотри что получится. Добейся чтобы работало так, как надо тебе. Потом затаскивай логику создания FIFO обратно, при том делай так, чтобы к моменту вызова open() в любой из программ, файл с таким именем существовал и это был бы один и тот же файл (а не так, чтобы кто-то открыл файл на чтение, а другая сторона удалила его, и создала новую иноду, которую пытается открыть на запись с O_NDELAY, но её никто не читает).

anonymous
()
Ответ на: комментарий от mashina

Я понимаю , что алгоритм такой :

в процессе- клиенте :

1. создать канал 2.открыть канал для записи 3.записать данные в канал 4. закрыть канал

в процессе- сервере :

1. создать канал ( с тем же именем , что и в клиенте) 2.открыть канал для чтения 3. прочитать данные 4. закрыть канал

NNN7
() автор топика
Ответ на: комментарий от NNN7

Нет . Просто не сталкивался с этим . Ищу решение уже целый день.

С чтением текстов когда-нибудь сталкивался? Без этого скила может вся жизнь уйти.

mashina ★★★★★
()

если внимательно почитать info libc, то там есть детальное разъяснение как работает fifo (и прочие IPC) с примерами.

MKuznetsov ★★★★★
()
Ответ на: комментарий от mashina

Сталкивался) передавал данные между дочерными и родительским процессом через файлы . Кажется , это похожий метод

NNN7
() автор топика
Ответ на: комментарий от NNN7

Сталкивался) передавал данные между дочерными и родительским процессом через файлы

А, например, с экрана монитора в себя?

mashina ★★★★★
()
Ответ на: комментарий от anonymous

Спасибо за совет) с командой mkfifo получается работать, всё работает верно

А можно ещё вопрос, если не сложно Вам ответить : не совсем понимаю предназначение флага O_NDELAY , нужен ли он вообще ?

Если установлен флаг O_NDELAY, то вызов open только на чтение завершается без задержки, а вызов open только для записи отрабатывает с сообщением об ошибке, если в данный момент нет процесса, открывшего файл для чтения; Если не установлен флаг O_NDELAY, то вызов open только на чтение блокируется, пока какой-либо процесс не откроет файл для записи, а вызов open только на запись блокируется, пока какой либо процесс не откроет файл на чтение.

Как-то сложно пишут о этом флаге...

NNN7
() автор топика
Ответ на: комментарий от mashina

Извините , но к чему Ваш сарказм ? Да , я понимаю, что всё есть в гугле . Но если бы я там нашёл ответ для себя , здесь бы не спрашивал .

Я ж не прошу за меня задание делать , как некоторые. Иногда просто нужно подтолкнуть в правильную сторону .

NNN7
() автор топика
Ответ на: комментарий от NNN7

А можно ещё вопрос, если не сложно Вам ответить : не совсем понимаю предназначение флага O_NDELAY , нужен ли он вообще ?

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

anonymous
()
Ответ на: комментарий от anonymous

То есть, если бы я поставил этот флаг в процессе-клиенте (процесс -сервер ждёт данных) , то он бы не смог передать данные ?

NNN7
() автор топика
Ответ на: комментарий от NNN7

Спи иди. Флаг влияет на поведение функции на той стороне, где ты его указал. Там всё нормальным языком написано и даже по-русски. От того, что я тебе ещё раз напишу то, что написано в твоей же цитате, у тебя понимание не наступит.

anonymous
()
Ответ на: комментарий от anonymous

Это частный случай файлов. Ведь всё есть файл.

anonymous
()
Ответ на: комментарий от MKuznetsov

если внимательно почитать info libc

-rw-r--r--     root     root        94252 Jun 30 17:46 /usr/share/info/libc.info-1.gz
-rw-r--r--     root     root        72664 Jun 30 17:46 /usr/share/info/libc.info-10.gz
-rw-r--r--     root     root        52846 Jun 30 17:46 /usr/share/info/libc.info-11.gz
-rw-r--r--     root     root        92879 Jun 30 17:46 /usr/share/info/libc.info-2.gz
-rw-r--r--     root     root        92935 Jun 30 17:46 /usr/share/info/libc.info-3.gz
-rw-r--r--     root     root        88832 Jun 30 17:46 /usr/share/info/libc.info-4.gz
-rw-r--r--     root     root        74319 Jun 30 17:46 /usr/share/info/libc.info-5.gz
-rw-r--r--     root     root        77378 Jun 30 17:46 /usr/share/info/libc.info-6.gz
-rw-r--r--     root     root        96433 Jun 30 17:46 /usr/share/info/libc.info-7.gz
-rw-r--r--     root     root        89831 Jun 30 17:46 /usr/share/info/libc.info-8.gz
-rw-r--r--     root     root        41454 Jun 30 17:46 /usr/share/info/libc.info-9.gz
-rw-r--r--     root     root        19405 Jun 30 17:46 /usr/share/info/libc.info.gz

то можно сдохнуть. Пусть с утра методичку купит и почитает, а такие советы в сентябре надо было давать.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

если внимательно почитать info libc

то можно сдохнуть.

Всего-то 20-30 страничек текста:

[mr.president@whitehouse.gov.us ~]$ info libc 2>/dev/null | wc -l
71941

Можно и не сдохнуть.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.