使用管道发送消息 - C.

时间:2016-12-29 00:12:12

标签: c pipe

我想创建NO_PROC进程,这样每个进程都会从其父进程中读取消息,然后将这些消息和另外一条消息写入其子进程,除非最后一个进程将其消息写入其中stdout。因此, i' 进程将收到 i-1 消息,并将发送给子 i 消息。我必须使用管道进程之间的通信。我写了代码,但有些东西是错的,我找不到任何错误:/。当NO_PROC = 5我希望输出看起来像4行"我的消息",但在输出中我有一行:"我的消息"和3个空行,就像3个消息是空字符串:/。请注意,err.h是我的库,当出现问题时,它会向我提供函数syserr()

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "err.h"

#define NO_PROC 5
#define BUF_SIZE 20

char message[] = "my message";
int parent;
char buf[BUF_SIZE];

int main()
{
    for (int i = 0; i < NO_PROC; ++i) {
        int pipe_dsc[2], buf_len;
        if (pipe(pipe_dsc) == -1)
            syserr("Error in pipe\n");
        pid_t pid = fork();
        if (pid == -1)
            syserr("Error in fork\n");
        else if (pid == 0)
            parent = pipe_dsc[0];
        else {
            for (int j = 0; j < i; ++j) {
                if ((buf_len = read(parent, buf, BUF_SIZE - 1)) == -1)
                    syserr("Error in read\n");
                buf[buf_len < BUF_SIZE - 1 ? buf_len : BUF_SIZE - 1] = '\0';
                if (i == NO_PROC - 1)
                    printf("%s\n", buf);
                else if (write(pipe_dsc[1], buf, sizeof(buf)) != sizeof(buf))
                    syserr("Error in write\n");
            }
            if (i < NO_PROC - 1 && write(pipe_dsc[1], message, sizeof(message)) != sizeof(message))
                syserr("Error in write\n");
            if (wait(0) == -1)
                syserr("Error in wait\n");
            return 0;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我认为你过度复杂化和/或使用了错误的方法。您不必将 i 消息发送到 i 进程。由于 ith 进程是 i-1th 进程的副本(分支),因此它已收到 i-1 消息,只需要一个更多。这是一个相当对称(和学术)的问题。

以下是一个示例(省略强健错误检查)。请注意,这依赖于原子管道写入,只要您不编写大于PIPE_BUF的消息(参见man pipe),就可以了。

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

void syserr(char * msg) { printf("%s\n", msg); exit(1); }
#define NO_PROC 5
#define BUF_SIZE 100
char message[] = "my message ";

int main() {
    int message_len = 0;
    char buf[BUF_SIZE];
    for (int i = 0; i < NO_PROC; ++i) {
        int pipe_dsc[2], buf_len;
        if (pipe(pipe_dsc) == -1) {
            syserr("Error in pipe\n");
        }
        pid_t pid = fork();
        if (pid == -1) {
            syserr("Error in fork\n");
        }
        else if (pid == 0) {
            close(pipe_dsc[1]);
            int n = read(pipe_dsc[0], buf+message_len, sizeof(buf));
            message_len = strlen(buf); // Assume message is null terminated string.
            if(i == NO_PROC -1) {
                printf("Process %i: received '%s'\n", i+1, buf);
            }
        }
        else {
            close(pipe_dsc[0]);
            write(pipe_dsc[1], message, sizeof(message));
            wait(0);
            return 0;
        }
    }
}