c - 在 C/Linux 中使用命名管道和 fork

标签 c linux fork named-pipes

我正在尝试编写简单的控制台应用程序,它从用户那里读取文本,然后将小写字母更改为大写字母,最后在控制台中打印结果。 当我只使用一个管道时它工作正常(例如,不从控制台读取文本),但当我使用两个时它的工作完全不可预测。

“[Write]”不应该等待“[To upper]”直到它发送文本吗?

我得到以下输出:

[Write] Waiting for txt to diplay.
[To upper] Waiting for txt to change.
[Write] Received following txt:
[To upper] Received txt ().
[To upper] Changed txt send to [Write] ().
[Scan] Type your txt:
[Scan] Txt received. Sending to [To upper] (y)

我的代码:

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#define SIZE 16
int main()
{
    int i=0;
    int f1,f2;
    char x[SIZE]={0};
    if( fork() )    
    {
        if( fork() )//[Write]
        {
            f1=open("upper-write",O_RDONLY);
            puts( "[Write] Waiting for txt to diplay." );
            read( f1, &x, sizeof( x ) );
            printf( "[Write] Received following txt: %s\n", x );
            close( f1 );
        }
        else//[Scan]
        {
            puts( "[Scan] Type your txt: " );
            //scanf ("%15s",x);//scanf not working now, so I change my char array by myself     
            x[0]='y';
            f2=open("scan-upper",O_WRONLY);
            printf( "[Scan] Txt received. Sending to [To upper] (%s)\n", x );
            write( f2, &x, sizeof( x ) );
            close( f2 );
        }
    } 
    else//[To upper]
    {
        puts( "[To upper] Waiting for txt to change." );
        f2=open("scan-upper",O_RDONLY);
        read( f2, &x, sizeof( x ) );
        close( f2 );

        printf( "[To upper] Received txt (%s).\n" ,x);  
        for(i=0;i<SIZE;i++)
            if(x[i]>=97 && x[i] <=122)//lowercase -> uppercase
                x[i]-=32;


        f1=open("upper-write",O_WRONLY);
        write( f1, &x, sizeof( x ) );
        printf( "[To upper] Changed txt send to [Write] (%s).\n" ,x);
        close( f1 );
    }
}

最佳答案

我认为您需要了解一些事情才能理解问题。首先,在 fork() 之后,无法保证哪个进程先运行。其次,如果管道的另一端未打开以进行写入,read() 会立即返回零值。

您指望进程以特定顺序运行,以便在进行任何读取之前管道在两侧都打开。由于这种情况并不总是发生,read() 并不总是阻塞。

您可以通过在 fork() 之前打开所有管道的两端来解决这个问题。所有进程都将在管道的两端都有文件描述符。只需在相应进程中不需要的文件描述符上调用 close()

关于c - 在 C/Linux 中使用命名管道和 fork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30328987/

相关文章:

C 套接字 : What would cause the accept function to return -1

c - 我如何遍历 bash 中的位置变量?

c - 为什么 getline() 会得到前一行?

linux - 现实生活中的 Docker 容器

git - 为什么我们需要在我们的 fork 存储库中创建一个分支来推送我们的更改,然后创建一个 pull 请求到上游存储库?

c - 我在使用字符串通过引用传递时遇到问题

linux - 如何为一些行运行 awk。?

mysql - 在 Linux 中使用 MySQL "error: unknown type name ‘uint’ 编译 C 项目时出错

python - 分别改变并行进程中的不同python对象

c - Fork() 有多个 child 并等待他们全部完成