写入管道或管道

时间:2011-10-30 17:20:16

标签: c unix named-pipes

理论上这样做的最佳方法是什么?我需要让用户输入要发送到管道的进程数量,例如“3”,并且在每次迭代时循环通过三个 [three whats?] 我需要创建一个进程,将 [what?] 发送到管道并打印出来。

下次用户输入另一个号码时,说“4”,它应该打印前一个3 + 1 ..我正在研究这个但是无法理解它是怎么做的。这是我的代码。我只需要指导,不需要尝试为我解决(但建议将不胜感激)。

现在我可以通过管道发送一个并返回它,但管道关闭,它不允许其他进程进入。

1 个答案:

答案 0 :(得分:0)

建议#1:使用功能

使用功能,即使是小工作,例如:

void create_fifo(const char *name)
{
    /* Create the first named - pipe */
    int ret_val = mkfifo(name, 0666);

    if ((ret_val == -1) && (errno != EEXIST))
    {
        perror("Error creating the named pipe");
        exit(1);
    } 
}

现在你可以简单地写一下你的主程序:

create_fifo(PIPE1);
create_fifo(PIPE5);

这减少了主程序中的混乱。它也坚持敏捷原则DRY - 不要重复自己。

建议#2:错误检查系统调用。

你这样做是为了创建FIFO,这很好。您不需要open()来电或read()write()来电。你可能应该。我在我的程序中使用类似于以下的函数:

#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

static const char *arg0 = "did not call err_setarg0(argv[0])";

void err_setarg0(const char *argv0)
{
    arg0 = argv0;
}

void err_exit(const char *fmt, ...)
{
    int errnum = errno;   /* Capture errno before it is changed */
    va_lists args;
    fprintf(stderr, "%s: ", arg0);
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    if (errnum != 0)
        fprintf(stderr, "%d: %s\n", errnum, strerror(errnum));
    exit(1);
}

然后您可以使用:

if ((rdfd1 = open(PIPE1, O_RDONLY)) < 0)
    err_exit("Failed to open FIFO %s for reading: ", PIPE1);
if ((wrfd1 = open(PIPE5, O_WRONLY)) < 0)
    err_exit("Failed to open FIFO %s for writing: ", PIPE5);

建议#3:制作迭代服务器

您的服务器程序当前打开FIFO一次,然后从一个读取,写入另一个,并终止。你需要在这段代码的某些部分循环,可能是两个嵌套循环。您必须决定在EOF之前是否需要读取内部循环。您还需要知道如何终止服务器。

建议#4:服务器可能需要管道名称作为参数

您的服务器当前使用固定FIFO名称。您可能需要它将输入和输出文件名作为命令行参数,这样当您的客户端生成多个服务器时,每个服务器可以拥有自己的一组FIFO,而不是所有共享相同的两个FIFO的进程,这将导致混乱和混乱。

事实上,生成名称的需要使整个设计受到质疑 - 你确定使用FIFO是最好的方法吗?在我看来,匿名管道可以为您提供更好的服务;您不必创建名称,服务器只需读取其标准输入并将(修改后的?)数据写入其标准输出,因此您甚至可以简单地使用cattrsed或...作为您的服务器。

显然,如果你使用管道,你需要做一些小心的管道,但你还需要仔细管理每台服务器的FIFO对。