抱歉,这篇文章太长了。。。我在这件事上遇到了无数的问题。首先我要说我是一个学生,我的教授是一个毫无价值的资源。所以,我要做的就是使用producer fork,然后父producer将在一个文件中计算一些内容,并将两个int发送给consumer,这是由子进程启动的。我已经测试了所有的东西,fork和file都工作了,我到处都有printf语句,所以我知道正在做什么,代码在哪里。
当我添加

if (pipe(pipefd) == -1) {
   perror("pipe");
}

这让我父母不得不终止协议。它到达“母管打开”,但随后死亡。我查了一下$ps看它是不是刚挂起来的,但它不在那儿,它只是死了。如果我把这个片段去掉,它会一直运行到最后,但我假设如果代码不在那里,那么它实际上并不知道pipefd是一个管道。。。正确的?
我在这个网站上做了搜索,找到了另一个例子,并遵循他的做法和答案,我只是拒绝工作。我很确定这是一件很容易解决的小事,但我已经没有办法尝试什么了:(
我真的不想把我所有的代码都发出去,因为这将是一堵巨大的文字墙,但我也不想意外地删掉一些原来很重要的东西。
制作人c
#include <stdio.h>      /* printf, stderr, fprintf */
#include <sys/types.h>  /* pid_t */
#include <unistd.h>     /* _exit, fork, execl */
#include <stdlib.h>     /* exit */
#include <errno.h>      /* errno */
#include <string.h>     /* strlen */
#include <sys/wait.h>   /* wait */

#define SLEEP_TIME 8

int main (int argc, char *argv[]){
    //PID
    pid_t local_pid;
    local_pid = fork();

    //Logic to determine if the process running is the parent or the child
    if (local_pid == -1) {

        /* Error:
        * When fork() returns -1, an error happened
        * (for example, number of processes reached the limit).
        */
        fprintf(stderr, "can't fork, error %d\n", errno);
        exit(EXIT_FAILURE);

    } else if (local_pid == 0) {

        //Child specific code
        int child;
        char *temp[] = {NULL};
        printf("Child PID found\n");
        child = execv("./consumer", temp);

        _exit(0);


    } else {
        //Parent specific code
        printf("Parent running\n");
        //open file
        FILE * randStrings;
        randStrings = fopen("randStrings.txt", "r");
        int file_length;
        int num_of_e = 0;
        int c;          //using this as a char


        //until eof
        while (feof(randStrings) == 0) {
            c = fgetc(randStrings);
            //calculate length of file
            file_length++;
            //count e chars
            if (c == 'e') {
                num_of_e++;
            }
        }

        //close file
        fclose(randStrings);

        //send bundle to child
        int a[2];
        a[0] = num_of_e;
        a[1] = file_length;

        printf("num of e = %i\n", a[0]);
        printf("len = %i\n", a[1]);

        //set up parent pipe
        int pipefd[2];

        if (pipe(pipefd) == -1) {
            perror("pipe");
            printf("x\n");
        }
        printf("parent pipe open\n");
        close(pipefd[0]); //close the read end
        write(pipefd[1], &a[0], sizeof(int));
        write(pipefd[1], &a[1], sizeof(int));
        close(pipefd[1]);
        printf("parent pipe closed\n");

        //wait for child to finish running
        wait(NULL);
        printf("parent out\n");
        //terminate
    }
}

和消费者
#include <stdio.h>      /* printf, stderr, fprintf */
#include <sys/types.h>  /* pid_t */
#include <unistd.h>     /* _exit, fork, execl */
#include <stdlib.h>     /* exit */
#include <errno.h>      /* errno */

#define SLEEP_TIME 5

int main (int argc, char *argv[]){

    sleep(SLEEP_TIME);
    printf("Child program launched\n");

    //receive bundle
    int pipefd[2];
    int buf[2];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        printf("child x\n");
    }

    close(pipefd[1]); //child closes write end

    buf[0] = 0;
    buf[1] = 0;

    /*int i = 0;        // i dont like this
    while (read(pipefd[0], &buf[i], sizeof(int)) > 0) {
        i++;
    }*/
    printf("child reading pipe\n");

    read(pipefd[0], &buf[0], sizeof(int));
    read(pipefd[0], &buf[1], sizeof(int));

    close(pipefd[0]);
    //buf should have the stuff in it
    int num_of_e = buf[0];
    int file_length = buf[1];
    printf("child num of e = %i\n", num_of_e);
    printf("child len = %i\n", file_length);

    //open file
    FILE * resultStrings;
    resultStrings = fopen("resultStrings.txt", "w");

    for (int i = 0; i < num_of_e; i++) {
        //write num_of_e e chars
        fputc('e', resultStrings);
    }
    //or if no e chars, write - chars
    if (num_of_e == 0) {
        for (int i = 0; i < file_length; i++) {
            //write file_length '-' chars
            fputc('-', resultStrings);
        }
    }
    //close file
    fclose(resultStrings);
    printf("child out\n");
}

如果你在这之后还留在这里,你应该得到一个感谢,因为这段时间太长了。

最佳答案

你做错了。整个机制起作用是因为子进程继承父进程的打开文件描述符。
应该是这样的:
pipe(pipefd)打开管道
fork()
母公司(生产商):
关闭读取端(pipefd[0]
写入写入端(pipefd[1]
儿童(消费者):
关闭写入端(pipefd[1]
从读取端读取(pipefd[0])或调用exec
您正在父进程和子进程中打开不同的管道(在您forked之后),它需要在您fork之前发生。
既然您正在使用,那么新进程需要注意只读管道。有几种方法可以做到这一点:
在命令行上传递文件描述符编号(exec
pipefd[0]它是新执行进程的标准

关于c - IPC的新手,无法使用我的管道,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19530263/

10-10 23:36