我的问题是如何控制关于管道的流程执行,特别是using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
void run()
{
Task.Factory.StartNew(resetFlagAfter1s);
var waiter = Task.Factory.StartNew(waitForFlag);
waiter.Wait();
Console.WriteLine("Done");
}
void resetFlagAfter1s()
{
Thread.Sleep(1000);
flag = false;
}
void waitForFlag()
{
int x = 0;
while (flag)
{
++x;
// Uncommenting this line make this thread see the changed value of flag.
// Console.WriteLine("Spinning");
}
}
// Uncommenting "volatile" makes waitForFlag() see the changed value of flag.
/*volatile*/ bool flag = true;
static void Main()
{
new Program().run();
}
}
}
/ wait
函数的实现。
当我为以下命令waitpid
创建管道时,我执行以下操作:
ls | head -3
命令,关闭子项中管道的输出端head -3
命令,关闭父级管道的输入端我的问题:based on this discussion,我确实需要等待孩子完成执行,即执行ls
。但是我如何/在哪里实现head -3
函数的方式不会与waitpid
命令冲突?
基于this great text,描述如下:
如果父母想要从孩子那里接收数据,它应该关闭fd1,孩子应该关闭fd0。如果父母想要向孩子发送数据,它应该关闭fd0,孩子应该关闭fd1。由于描述符在父级和子级之间共享,因此我们应始终确保关闭我们不关心的管道末尾。从技术角度来说,如果未明确关闭管道的不必要的末端,则永远不会返回EOF。
因此,在执行之前,孩子必须等待父母完成管道。
我还看过一些示例,其中两个叉子用于管道的一个过程。是否可以避免僵尸进程,就像我的APUE ch.8副本中的描述一样?
考虑以下代码实现:
close[]
我必须承认,我在StackExchange上查看了很多类似的问题。然而,几乎所有这些都具有特定的内容。我正在寻找的是原理的解释和功能的组合。谢谢你的时间!
答案 0 :(得分:0)
你不能都想等孩子和高管。所以你需要有两个孩子。有两种常见的方法可以做到这一点,或者有一个父进程创建两个直接子进程,然后可以/必须等待两者;或者让一个孩子自己创建第二个孩子,这样父母只需等待一个过程终止。
选项1 (继承管道)
pipe(pi);
pid1 = fork();
if (pid1==0) { // child1
// make redirections
exec("head"...);
}
pid2 = fork();
if (pid2==0) { // child2
// make redirections
exec("ls"...);
}
// parent process
// close unuseful pipe
waitpid(pid1...);
waitpid(pid2...);
选项2 (管道只对相关进程可见)
pid1 = fork();
if (pid1==0) { // child
pipe(pi);
pid2 = fork();
if (pid2==0) { // gran child
// make redirections
exec("ls"...);
}
// make redirections
exec("head"...);
}
// parent process
waitpid(pid1...);