1

I want to make a simple program, that fork, and the child writes into the named pipe and the parent reads and displays from the named pipe. The problem is that it enters the parent, does the first printf and then it gets weird, it doesn't do anything else, does not get to the second printf, it just ways for input in the console.

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void main()
{
char t[100];
mkfifo("myfifo",777);
pid_t pid;
pid = fork();
if (pid==0)
{
    //execl("fifo2","fifo2",(char*)0);
    char r[100];
    printf("scrie2->");
    scanf("%s",r);

    int fp;
    fp = open("myfifo",O_WRONLY);
    write(fp,r,99);
    close(fp);
    printf("exit kid \n");
    exit(0);
} else
{
    wait(0);
    printf("entered parent \n"); // <- this it prints
    // whats below this line apparently its not being executed
    int fz; printf("1"); 
    fz = open("myfifo",O_RDONLY); printf("2");
    printf("fd: %d",fz);
    char p[100];
    int size;
    printf("------");
    //struct stat *info;
    //stat("myfifo",info); printf("%d",(*info).st_size);
    read(fz,p,99);
    close(fz);
    printf("%s",p);

    printf("exit"); exit(0);
}
}
4

2 回答 2

5

你真的应该检查函数调用的返回值是否有错误,尤其是mkfifo()open().

您的呼叫wait()将导致其当前位置出现问题。打开 FIFO 进行读取通常会阻塞,直到其他进程打开相同的 FIFO 进行写入,反之亦然1。父进程正在等待子进程终止,子进程正在等待读取进程,即父进程连接到 FIFO。

1 - 请参阅open()下面的注释以使用O_NONBLOCKFIFO

wait()调用移至父进程退出之前以及更改调用中的模式mkfifo()似乎0666可以解决您的一些直接问题。

完成 FIFO 后移除 FIFO 也是一种很好的做法。

unlink("myfifo");

open()IEEE Std 1003.1-2004 中的功能文档

打开设置了 O_RDONLY 或 O_WRONLY 的 FIFO 时:

  • 如果设置了 O_NONBLOCK,则只读的 open() 应立即返回。如果当前没有进程打开文件进行读取,则用于只写的 open() 将返回错误。

  • 如果 O_NONBLOCK 被清除,只读的 open() 将阻塞调用线程,直到线程打开文件进行写入。只写的 open() 将阻塞调用线程,直到线程打开文件进行读取。


以下示例是原始问题中的代码Beej's Guide to Unix IPC 的 FIFO 页面的组合:

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

#define FIFO_NAME "myfifo"

int main(void)
{
    char buf[256];
    int num, fd;
    pid_t pid;

    if (mkfifo(FIFO_NAME, 0666) < 0)
        perror("mkfifo");

    pid = fork();
    if (pid == 0)
    {
        printf("child - waiting for readers...\n");
        if ((fd = open(FIFO_NAME, O_WRONLY)) < 0)
            perror("child - open");
        
        printf("child - got a reader -- type some stuff\n");
        while (fgets(buf, sizeof(buf), stdin), !feof(stdin))
        {
            if ((num = write(fd, buf, strlen(buf))) < 0)
                perror("child - write");
            else
                printf("child - wrote %d bytes\n", num);
        }

        close(fd);
        exit(0);
    }
    else
    {
        printf("parent - waiting for writers...\n");
        if ((fd = open(FIFO_NAME, O_RDONLY)) < 0)
            perror("parent - open");
        
        printf("parent - got a writer\n");
        do
        {
            if ((num = read(fd, buf, sizeof(buf))) < 0)
                perror("parent - read");
            else
            {
                buf[num] = '\0';
                printf("parent - read %d bytes: \"%s\"\n", num, buf);
            }
        } while (num > 0);

        close(fd);
        wait(0);
    }

    unlink(FIFO_NAME);
    return 0;
}

此示例在 Linux 中进行了测试。按Ctrl-D终止程序。

于 2010-05-29T15:59:15.983 回答
3

First of all, try fprintf to stderr instead of printf (to stdout)

The stderr is unbuffered.

Then you can tell what actually gets printed and what does not.

or at least add fflush before waiting for anything.

于 2010-05-29T15:11:40.313 回答