我有一段遗留代码,我将某些逻辑委托给子进程。要求是父级写入管道并且子级读取它。在阅读之后,孩子将东西写入新管道并且父母从中读取。
在下面的代码中,函数send()由父进程中的专用线程定期调用。
LaunchWorker()确保子进程仅在第一次调用时进行分叉。
1)我无法弄清楚如何关闭两个描述符的读写端,以便在每次写操作时刷新写入管道的旧数据。 2)还有两个描述符需要两次调用pipe()吗?
任何使此代码有效的输入将不胜感激。 谢谢!
typedef struct
{
WebClient* wc; // user defined class
string url;
string data;
size_t dataLen;
DownloadObserver* downloadCallback; // user defined class
string* token;
}Payload;
PayLoad pl;
static pid_t worker_pid = 0;
int fd1[2];
int fd2[2];
bool done = false;
void LaunchWorker()
{
if (worker_pid != 0)
{
return;
}
pipe(fd1);
pipe(fd2);
worker_pid = fork();
}
void send()
{
//populate pl;
LaunchWorker();
if (worker_pid == 0)
{
while(true)
{
close(fd1[1]);
close(fd2[0]);
int cr = read(fd1[0], &pl, sizeof(Payload));
if (cr > 0)
{
// Upload some data to a remote http endpoint - uses libcurl
//if upload success, done = true
int cw = write(fd2[1], &done, sizeof(bool));
if (cw > 0)
{
// success
}
else
{
// failure
}
}
else
{
// failure
}
}
}
else if (workper_pid > 0)
{
close(fd1[0]);
close(fd2[1]);
int pw = write(fd1[1], &pl, sizeof(Payload));
if (pw > 0)
{
int pr = read(fd2[0], &done, sizeof(bool));
if (pr > 0)
{
// do something with value read
}
else
{
// failure
}
}
else
{
failure
}
}
}
答案 0 :(得分:0)
首先,您需要在fork之后立即关闭管道的未使用端,因此父级应该关闭fd1的读取结束和fd2的写入结束,子应该关闭写入fd1的结束和fd2的读取结束。如果不这样做,完成后管道将不会关闭。
然后,当你想要停止一切时,我会让每个管道的编写器关闭管道的写入端。即
如果孩子开始关闭,反之亦然。
最后,父进程应发出wait
系统调用以收集子进程的退出结果。
是的,你确实需要两个管道。管道是单向的。