我们最近在应用的OS设计类中引入了fork(),我对它的了解并不是很好。我们需要使用它在C文件中创建四个独立的进程,然后将其中三个进程写入命名管道,而第四个进程从中读取。
这是我到目前为止尝试过的代码:
// creating the named pipe
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0);
int myPipe;
const char* colour;
pid_t p1, p2;
p1 = fork();
if (p1 < 0)
{
printf("Fork failed\n");
}
else if (p1 == 0) // this is the child of p1, we'll call it "red"
{
printf("\nPid %d %s", getpid(), "(red) started\n");
myPipe = open("/tmp/namedpipe", O_WRONLY);
colour = "RED\n";
write(myPipe, colour, strlen(colour) +1);
close(myPipe);
}
else // the is the parent of p1, we'll call it "green"
{
printf("\nPid %d %s", getpid(), "(red) started\n");
myPipe = open("/tmp/namedpipe", O_WRONLY);
colour = "RED\n";
write(myPipe, colour, strlen(colour) +1);
close(myPipe);
p2 = fork();
if (p2 < 0)
{
printf("Fork failed\n");
}
else if (p2 == 0) // this is the child of p2, we'll call it "blue"
{
printf("\nPid %d %s", getpid(), "(blue) started\n");
myPipe = open("/tmp/namedpipe", O_WRONLY);
colour = "BLU\n";
write(myPipe, colour, strlen(colour) +1);
close(myPipe);
}
else // the is the parent of p2, we'll call it "reader"
{
printf("This is the reader process");
myPipe = open("/tmp/namedpipe", O_RDONLY);
char nextChar;
while (read(myPipe, &nextChar, 1) == 1)
printf("%c", nextChar);
close(myPipe);
}
}
如果你注释掉所有与管道相关的语句,这段代码似乎工作正常,但是否则它执行前两个print语句然后挂起,强制使用CTRL-C。我不确定问题是在分叉还是与我写作和阅读管道的方式有关。请告诉我。
答案 0 :(得分:4)
在没有O_NONBLOCK
的情况下打开的命名管道在进程之间同步。如果进程尝试打开以进行写入,它将阻塞,直到某些其他进程尝试打开以进行读取。如果订单被颠倒,则读取过程将被阻止,直到写入过程尝试打开。无论哪种方式,两者同时打开成功。
在你的程序中,你创建了一个子程序“red”,它试图打开写入,而父程序“green”也试图打开写入。还没有人阅读,所以两者都被阻止了。未达到创建其他2个进程的代码,因为它是在“绿色”进程中打开后阻塞它的。
答案 1 :(得分:2)
打开管道进行书写。这将阻塞,直到打开管道进行读取。 由于父母不会分叉更多的孩子,所以它都会停止。
我无法访问Unix平台,因此我没有尝试编译它,但您可以尝试之类的:
// creating the named pipe
#define CHILD_COUNT 3
mknod("/tmp/namedpipe", S_IFIFO | 0600, 0);
const char* childname[CHILD_COUNT] = { "Red", "Blue", "Yellow" };
const char* colorname[CHILD_COUNT] = { "RED\n", "BLUE\n", "YELLOW\n" };
int myPipe;
const char* colour;
pid_t p;
int i;
for (i=0; i<CHILD_COUNT; i++)
{
p = fork();
if (p < 0) {
printf("Fork failed\n");
}
else if (p == 0) // this is a child, do child stuff
{
printf("\nPid %d (%s) started\n", getpid(), childname[i]");
myPipe = open("/tmp/namedpipe", O_WRONLY);
colour = colorname[i]; // =="RED\n" for first child
write(myPipe, colour, strlen(colour) +1);
close(myPipe);
return;
}
// else it's the parent, spawn more children
}
// Parent
printf("This is the reader process");
myPipe = open("/tmp/namedpipe", O_RDONLY);
char nextChar;
while (read(myPipe, &nextChar, 1) == 1)
printf("%c", nextChar);
close(myPipe);