【发布时间】:2017-03-20 15:30:10
【问题描述】:
我有一段遗留代码,我在其中将某些逻辑委派给子进程。要求是父级写入管道,子级读取管道。读完后,子进程向新管道写入内容,父进程从中读取。
在下面的代码中,函数 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
}
}
}
【问题讨论】:
-
是的,您需要调用
pipe两次,以创建两个管道。这是因为管道是单向的,它们只是单向的。 -
谢谢。关于我的第一个问题,关于我应该在代码中调用 close() 的顺序的任何提示?
-
您应该关闭每个进程中不使用的描述符(例如,子进程中的
fd1[1])。除此之外,您不需要关闭任何管道描述符。我不确定你需要什么样的“同步”?您是否正在发送大量数据?Payload的大小是多少? -
谢谢。我已经使用 Payload 结构定义编辑了代码,并添加了对 close() 的调用。 sizeof(Payload) 为 80。另请参阅下面我对 JeremyP 对我所看到的问题的回答的评论。我完全迷失了为什么第二次阅读不起作用。
-
一个可能的问题是您在进程之间传输指针。一旦进程与
fork调用分开,它们就会有不同的内存映射。指向fork之后分配的一些内存的指针在其他进程中将无效。
标签: c linux embedded-linux