理论上这样做的最佳方法是什么?我需要让用户输入要发送到管道的进程数量,例如“3”,并且在每次迭代时循环通过三个 [three whats?] 我需要创建一个进程,将 [what?] 发送到管道并打印出来。
下次用户输入另一个号码时,说“4”,它应该打印前一个3 + 1 ..我正在研究这个但是无法理解它是怎么做的。这是我的代码。我只需要指导,不需要尝试为我解决(但建议将不胜感激)。
现在我可以通过管道发送一个并返回它,但管道关闭,它不允许其他进程进入。
答案 0 :(得分:0)
使用功能,即使是小工作,例如:
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 - 不要重复自己。
你这样做是为了创建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);
您的服务器程序当前打开FIFO一次,然后从一个读取,写入另一个,并终止。你需要在这段代码的某些部分循环,可能是两个嵌套循环。您必须决定在EOF之前是否需要读取内部循环。您还需要知道如何终止服务器。
您的服务器当前使用固定FIFO名称。您可能需要它将输入和输出文件名作为命令行参数,这样当您的客户端生成多个服务器时,每个服务器可以拥有自己的一组FIFO,而不是所有共享相同的两个FIFO的进程,这将导致混乱和混乱。
事实上,生成名称的需要使整个设计受到质疑 - 你确定使用FIFO是最好的方法吗?在我看来,匿名管道可以为您提供更好的服务;您不必创建名称,服务器只需读取其标准输入并将(修改后的?)数据写入其标准输出,因此您甚至可以简单地使用cat
或tr
或sed
或...作为您的服务器。
显然,如果你使用管道,你需要做一些小心的管道,但你还需要仔细管理每台服务器的FIFO对。