更新了C中的命名管道永远无法得到我所期望的

时间:2016-12-22 00:42:55

标签: fork mkfifo

我目前正在开展一个涉及4个通过命名管道进行通信的流程的项目。但是,我不会总是得到我期望的结果。作者只是发送一个等于进程pid的int。

这是我用来说明问题的简短可执行代码:

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>

int main(void){
int i, j, k, pid;
int childs = 4;
int size = 16;
char nomTube[size];

for(j = 0; j < childs; j++)
{
sprintf(nomTube, "assistant%d.fifo", j);
if(mkfifo(nomTube, 0777) != 0) 
{
    fprintf(stderr, "Impossible de créer le tube nommé.\n");
    //exit(EXIT_FAILURE);
}
}

for(i = 0; i < childs; i++)
{
if(fork() == 0)
{
    pid = i;
    if(pid % 2 == 0)
        {Writing(pid); printf("Child(%d) writing done;\n", pid);}
    else
        {Reading(pid); printf("Child(%d) reading done;\n", pid);}
    break;
}
}

for(k = 0; k < childs; k++)
{
wait(NULL);
}

return 0;}

现在写作功能:

void Writing(int pid){
int entreeTube;
int var = pid;
int i;
if(pid == 0)
{
for(i = 0; i < 2; i++)
{
    printf("Child(%d) i'm writing to Child(%d) var = %d;\n", pid, 1, var);
    if((entreeTube = open("assistant1.fifo", O_WRONLY)) == -1) 
    {
        fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
        //exit(EXIT_FAILURE);
    }
    write(entreeTube, &var, sizeof(int));
}
}
else if(pid == 2)
{
for(i = 0; i < 2; i++)
{
    printf("Child(%d) i'm writing to Child(%d) var = %d;\n", pid, 3, var);
    if((entreeTube = open("assistant3.fifo", O_WRONLY)) == -1) 
    {
        fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
        //exit(EXIT_FAILURE);
    }
    write(entreeTube, &var, sizeof(int));
}
}}

现在阅读功能:

void Reading(int pid){
int sortieTube;
int var = -1;
int i;

if(pid == 1)
{
for(i = 0; i < 2; i++)
{
    if((sortieTube = open ("assistant1.fifo", O_RDONLY)) == -1) 
    {
        fprintf(stderr, "Impossible d'ouvrir la sortie du tube nommé.\n");
        //exit(EXIT_FAILURE);
    }

    read(sortieTube, &var, sizeof(int));
    printf("Child(%d) var = %d\n", pid, var);
}
}
else if(pid == 3)
{
for(i = 0; i < 2; i++)
{
    if((sortieTube = open ("assistant3.fifo", O_RDONLY)) == -1) 
    {
        fprintf(stderr, "Impossible d'ouvrir la sortie du tube nommé.\n");
        //exit(EXIT_FAILURE);
    }

    read(sortieTube, &var, sizeof(int));
    printf("Child(%d) var = %d\n", pid, var);
}
}}

基本上是这样的:

  • 儿童(0)写入&#34; assistant1.fifo&#34; 2次|写0
  • Child(2)写入&#34; assistant3.fifo&#34; 2次|写道2
  • 孩子(1)读&#34; assistant1.fifo&#34; 2次|读0
  • 孩子(3)读&#34; assistant3.fifo&#34; 2次|读2

有时候它会起作用,但有时它会阻挡它。您可能需要执行几次才能看到它阻塞。

这是同步问题吗?即使写/读是阻塞的?

我不知道问题出在哪里......所以我想我错过了与管道技术相关的东西。你看到了什么错了吗?

我对代码编辑和缩进以及我的英语道歉,我希望你能够理解我。

1 个答案:

答案 0 :(得分:0)

我相信我找到了芒果。 我通过在写作和阅读中只打开mkfifo来解决问题。然后是写入或读取的循环。

    printf("Child(%d) i'm writing to Child(%d) var = %d;\n", pid, 1, var);
    if((entreeTube = open("assistant1.fifo", O_WRONLY)) == -1) 
    {
        fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
        //exit(EXIT_FAILURE);
    }
    for(i = 0; i < 2; i++)
    {
        write(entreeTube, &var, sizeof(int));
    }

阅读过程也一样。 即使它工作得很好,如果有人知道这一切背后的机制并且可以解释它们,我将不胜感激。 非常感谢你:))