Тупик при связи с дочерним процессом с перенаправленным вводом / выводом

Я пишу программу для программного взаимодействия с интерактивным модулем проверки модели SPIN. Для этого мне нужно перенаправить ввод / вывод SPIN, запустить его из моей программы, а затем периодически читать и записывать в него. Для тестирования я использую вместо вращения следующую короткую программу с одним входом и одним выходом:

#include <string>
#include <iostream>

using std::cin;
using std::cout;
using std::string;

void sprint(string s);
int main()
{
std::string s = "empty";
cin >> s;
cout << "\n\tthe text is: " << s;
return 0;
}

Моя программа, взятая в основном из этот ответ, является:

#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <cstring>
#include <unistd.h>
#include <errno.h>
#include <iostream>

#define PIPE_READ 0
#define PIPE_WRITE 1
#define maxReadSize 2048
using std::cout;
using std::cin;
using std::string;

int createChild(const char* szCommand, const char* aArguments, const char* szMessage);

int main()
{
createChild("./inout" , "inout", "hello");
return 0;
}int createChild(const char* szCommand, const char* aArguments, const char* szMessage)
{
int cStdinPipe[2];
int cStdoutPipe[2];
int nChild;
char nChar;
int nResult;

if (pipe(cStdinPipe) < 0)
{
return -1;
}
if (pipe(cStdoutPipe) < 0)
{
close(cStdinPipe[PIPE_READ]);
close(cStdinPipe[PIPE_WRITE]);
return -1;
}

nChild = fork();
if (0 == nChild)
{
// child continues here
cout.flush();
close(cStdinPipe[PIPE_WRITE]);

// redirect stdin
if (dup2(cStdinPipe[PIPE_READ], STDIN_FILENO) == -1)
{
exit(errno);
}

// redirect stdout
if (dup2(cStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1)
{
exit(errno);
}

// all these are for use by parent only
close(cStdinPipe[PIPE_READ]);
close(cStdoutPipe[PIPE_READ]);
close(cStdoutPipe[PIPE_WRITE]);

// run child process image
nResult = execlp(szCommand, aArguments, NULL);

// if we get here at all, an error occurred, but we are in the child
// process, so just exit
exit(nResult);
}
else if (nChild > 0)
{
// parent continues here
string messageFromChild = "";
string messageFromParent = "";
char readBuffer[maxReadSize];
int bytesWritten = 0;
int bytesRead = 0;

// close unused file descriptors, these are for child only
close(cStdinPipe[PIPE_READ]);
close(cStdoutPipe[PIPE_WRITE]);

// write to child
if (NULL != szMessage)
{
bytesWritten = write(cStdinPipe[PIPE_WRITE], szMessage, strlen(szMessage));
}

// read from child
bytesRead = read(cStdoutPipe[PIPE_READ], readBuffer, maxReadSize);

cout << "\nChild says: " << readBuffer << "\n";

// done with these in this example program, you would normally keep these
// open of course as long as you want to talk to the child
close(cStdinPipe[PIPE_WRITE]);
close(cStdoutPipe[PIPE_READ]);

std::cout << "\n\nParent ending";
}
else
{
// failed to create child
close(cStdinPipe[PIPE_READ]);
close(cStdinPipe[PIPE_WRITE]);
close(cStdoutPipe[PIPE_READ]);
close(cStdoutPipe[PIPE_WRITE]);
}
return nChild;
}

Запуск этой программы приводит к тупику, когда ребенок застревает cin и родитель на read(), Удаление любого из этих вызовов приводит к тому, что обе программы работают до завершения и нормально завершают работу. write() а также cout оба работают правильно.

0

Решение

Проблема оказалась в том, как read() а также write() работать над различными потоками / файлами / каналами. мой write() не мог общаться с read() что он закончил писать. Read() полагался на EOF который был отправлен только после того, как конец записи канала был закрыт. Конечно, как только он был закрыт, он исчез навсегда, и я не мог открыть его, чтобы отправить еще одно сообщение.

Поэтому я перешел на именованные каналы (fifo), чтобы я мог открывать трубы после каждой записи.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]