c - 写入一个或多个管道

标签 c unix named-pipes

从理论上讲,最好的方法是什么?我需要让用户输入要发送到管道的进程数,例如“3”,并且当它循环遍历三个 [三个什么?] 时,我需要在每次迭代中创建一个进程,将它[什么?] 发送到管道并打印出来。

下次用户输入另一个数字时,比如“4”,它应该打印之前的 3 + 1。我正在研究这个,但不明白该怎么做。这是我的代码。我只需要指导,无需尝试为我解决(但非常感谢建议)。

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

最佳答案

建议#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 是执行此操作的最佳方法吗?在我看来,匿名管道会更好地为您服务;您不必发明名称,服务器只需从其标准输入中读取并将(修改后的?)数据写入其标准输出,因此您甚至可以简单地使用 cat trsed 或 ... 作为您的服务器。

显然,如果您使用管道,则需要进行一些仔细的管道连接,但您还需要对每台服务器的 FIFO 对进行仔细的管道连接。

关于c - 写入一个或多个管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7946516/

相关文章:

linux - 有没有办法提高 linux 管道的性能?

c - 希望简化 C 中的 if 语句链

c - 如何在C中伪造用户输入

windows - RSync 仅复制文件夹目录结构而不复制文件

linux - `set -x` 有什么作用?

macos - 带有命令行输入重定向的 NSTask

wcf - 在 ASP.NET HttpModule 中使用 "named pipes"

c++ - 命名管道有时不起作用

c++ - 这个乘除函数正确吗?

C onefile 程序打印(在 stdout 上)自完成源代码