LINUX.ORG.RU

Pipe


0

1

Привет всем.

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

- родитель посылает сигнал - потомок в ответ присылает данные и снова засыпает

- родитель считывает данные, смотрит что бы все ОК и посылает потомку сигнал - умри - потомок завершается

Наверное, вывод у потомка буферезируется, поэтому только при его завершении выполняется запись в канал(такое у меня ощущение:) )

Проблема в этом и есть, что данные не считываются когда надо.

Родитель:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <fcntl.h>

extern int errno;
extern char **environ;

float res[2];
int *fd = new int[2];

#define BUF_SIZE 1024

int main(int argc, char **argv){

  if(argc==1){
    printf("\t1 paramete - digit.\n");
    exit(-1);
  }

  pipe(fd);
  perror("pipe");

  pid_t p_cos,p_pi;
  

// process get cos(x)
  switch(p_cos = fork()){
	case 0:
		close(fd[0]);
		dup2(fd[1],1);
		execl("~/Рабочий стол/lb4/bin/m_cos", "/",argv[1], NULL);
		perror("execl");
		exit(-1);
		break;
	case -1:
		perror("fork");
		exit(-1);
		break;
  }
 

  kill(p_cos,SIGUSR1);//Run
  perror("kil");
  printf("PId= %d\n",p_cos);

  close(fd[1]);

  char *buf = new char[BUF_SIZE];
  
  int i;
  
  i = read(fd[0],buf,BUF_SIZE);
  perror("read");
  printf("%s\ni=%d\n",buf,i);

return 0;
}

Потомок:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <wait.h>
#include <string.h>

char *arg_1;

void signal_run(int signum){ 

  float x=atof(arg_1);

  printf("%f\n",cos(x));

}

void signal_exit(int sig){

  exit(0);
  
}

int main(int argc, char **argv){

  arg_1 = argv[1];
  signal(SIGUSR1, signal_run); //Run process
  signal(SIGUSR2, signal_exit); //Exit process

  while (true){
	sleep(-1);
  }
  
return 0;
}

Компилю, запускаю, родитель зависает на

i = read(fd[0],buf,BUF_SIZE);

через командную строку посылаю kill -12 pid_потомка (-12 = SIGUSR2) потомок завершается, родитель считывает все верно..

Насчет реализации такой синхронизации не критикуйте, все так должно быть.. Это лаба :)


> #define BUF_SIZE 1024
> Компилю, запускаю, родитель зависает на
> i = read(fd[0],buf,BUF_SIZE);

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

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

read(fd[0],buf,BUF_SIZE) - Читает с канала, в буфер размером 1024 (размер, наверное, только что бы буфер не переполнить) аа.. Он ждет пока все 1024 символа не запишится??

Кажись понял, надо так:

i = read(fd[0],buf,0);//получаю число байт доступных в канале
i = read(fd[0],buf,i);//считываю число доступных байт

??

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

А динамика в линукс это зло?? Здесь не то что бы оправдано.. но все же..

зачем пишешь вот такую ерунду?

не понял

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

> i = read(fd[0],buf,0);//получаю число байт доступных в канале

man read

ssize_t read(int fd, void *buf, size_t count);

If count is zero, read() returns zero and has no other results.

ты кодишь вообще приходя в сознание?

arsi ★★★★★
()

Наск мне помнятся мои экзерсисы, данные будут подвисать в буфере, юзайте в потомке fflush после записи.

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

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

Наск мне помнятся мои экзерсисы, данные будут подвисать в буфере, юзайте в потомке fflush после записи.

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

Понял, спасибо!

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

> Скажите просто как надо тогда

man fcntl
/O_NONBLOCK

man poll

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

В линуксе это моя 3 программа (если их так можно назвать).. Тут я только начинаю учится..

А что, разве в «гольном» С есть разница между мастдаем и линуксом?

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

А чего у вас плюсовый код в сишной программе делает? Зачем?

Эт я не весь код выложил.. там функции с параметрами по умолчанию еще, и другие с++ возможности...

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

Кстати, а зачем все эти сигналы, если данную задачу можно было через простой popen сделать (в рамках той же лабораторки)? Или именно сигналы надо?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Kot

Тогда все на плюсах пишите, к чему такая мешанина?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Kot

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

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

> А что, разве в «гольном» С есть разница между мастдаем и линуксом?

Если «мастдаем» это Windows (первый раз просто слышу), то там пишу практически только на асме (все системное точно), а значит WinAPI пользуюсь.. На с++ не много в последнее время.. вот и подзабыл уже((

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

Вы бы условие лабораторной работы сказали, чтобы народ на вас не накидывался. Может, там все намного проще можно сделать :)

// а все-таки, плюсовый код и сишный мешать не стоит. Я, например, вообще не представляю, как в этом случае себя буферизованный ввод/вывод ведет. Ну или хотя бы буферизацию отключите...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Kot

Кстати, про

первый раз просто слышу

: ну не верю!!! Не может быть ЛОРовца, который не в курсе, что такое «мастдай» :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от AIv

> Кстати, а зачем все эти сигналы, если данную задачу можно было через простой popen сделать (в рамках той же лабораторки)? Или именно сигналы надо?

Именно сигналы надо. Да и посмотреть как и что.. просто попробывать мне тоже интересно.

Тогда все на плюсах пишите, к чему такая мешанина?

Тогда я наверное не особо разницу понимаю между С/С++ что там из чистого С чего нету в С++?? Или как Вы оприделили что это именно С-шный код с одной инструкцией с++ ??

Не тушуйтесь...

Та ничего, мне всегда интересно на свои ошибки посмотреть и так сказать уровень проверить :)

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

Или как Вы определили что это именно С-шный код с одной инструкцией с++ ??

Потому что это - чистый С, с одной-единственной «плюсовой» new :)

Именно сигналы надо

Тогда, вам уже отчасти подсказали :)

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

Потому что это - чистый С, с одной-единственной «плюсовой» new :)

Я же говорил, убрал кода много, там посуществу ничего не надо для форума.. Сразу и писал на чистом С, потом на С++, добавил С++ -ные инструкции..

: ну не верю!!! Не может быть ЛОРовца, который не в курсе, что такое «мастдай» :)

Посмотрел что такое «мастдай».. С «ЛОРовца» проблемы, в инете определения не нашел.. ((

Может, там все намного проще можно сделать :)

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

Да, уже полностью разобрался. Всем спасибо!!

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

> акцентируя внимание на вашей умственной неполноценности

ВотЪ. И ты это заметил?

Тогда у меня плохие новости для ТС. :\

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

Наск мне помнятся мои экзерсисы, данные будут подвисать в буфере, юзайте в потомке fflush после записи.

Вас что, всех накрыло конопляное облако? :)

pathfinder ★★★★
()

int *fd = new int[2];

pipe(fd);
perror(«pipe»);

дальше не читал.

nanoo_linux
()

ничего не понял в этом обсуждении ;)

но проблема ясна,

Наверное, вывод у потомка буферезируется,


именно. нужно просто заменить printf() в signal_run() на write().
или flush добавить.

read(fd[0],buf,BUF_SIZE) - это правильно. если хотя бы один
байт есть, он будет считан.

если нужно знать, сколько там уже есть байт - ioctl(FIONREAD)

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