首页 > 解决方案 > 如何使用 read() 从管道中读取

问题描述

我需要编写一个程序,使用祖先从输入文件写入通道,然后后代进程依次从管道读取并使用信号同步,但是,当子进程启动时,我得到 errno = 9 (错误的文件描述符)从通道读取时,可能是什么问题?您可以在下面看到父亲的代码,您可以在下面看到孩子的代码。父代码(main.cpp):

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>

using namespace std;

int main() {
    sigset_t new_mask;
    sigemptyset(&new_mask);
    sigaddset(&new_mask, SIGUSR1);
    sigaddset(&new_mask, SIGUSR2);
    sigaddset(&new_mask, SIGQUIT);
    sigprocmask(SIG_SETMASK, &new_mask, NULL);
    int fildes[2];
    pid_t pid1;
    pid_t pid2;
    int last_sig;
    pid1 = fork();
    if (pid1 == 0) {
        execl("1","1", "output1.txt", &fildes[0], &fildes[1],NULL);
        close(fildes[0]);
        _exit(0);
    }
    else {
        pid2 = fork();
        if (pid2 == 0) {
            execl("2","2", "output2.txt", &fildes[0], &fildes[1], NULL);
            close(fildes[0]);
            _exit(0);
        }
        else {
            close(fildes[0]);
            cout<<"Parent"<<endl;
            ifstream file("input.txt");
            if (file.is_open()) {
                string str;
                while(getline(file, str)){
                    write(fildes[1], &str[0], strlen(str.c_str()));
                    cout<<"PARENT пишет:" << str << endl;
                }
                close(fildes[1]);
                killpg(0, SIGQUIT);
                file.close();
            }
            int st1, st2;
            waitpid(pid1, &st1, 0);
            waitpid(pid2, &st2, 0);
            exit(EXIT_SUCCESS);

        }
    }

    return 0;
}

第一个孩子(1.cpp):

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>
#include <cerrno>  

using namespace std;

int main(int argc, char** argv) {
    close(*argv[3]);
    sigset_t mask_sig;
    sigemptyset(&mask_sig);
    sigaddset(&mask_sig, SIGUSR1);
    sigaddset(&mask_sig, SIGQUIT);
    ofstream file;
    int last_sig;
    char ch;
    file.open(argv[1], ios::app);
    sigwait(&mask_sig, &last_sig);
    file << read(*argv[2], &ch, 1)  << endl;
    file << errno << endl;
    while(read(*argv[2], &ch, 1) > 0){
        file << "z" << endl;
        file << ch;
        killpg(0, SIGUSR2);
        sigwait(&mask_sig, &last_sig);
    }
    killpg(0, SIGUSR2);
    file.close();
    return 0;
}

第二个孩子(2.cpp):

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <signal.h>
#include <wait.h>

using namespace std;

int main(int argc, char** argv) {
    close(*argv[3]);
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGQUIT);
    sigset_t mask_sig;
    sigemptyset(&mask_sig);
    sigaddset(&mask_sig, SIGUSR2);
    ofstream file;
    int last_sig;
    char ch;
    file.open(argv[1], ios::app);
    sigwait(&mask, &last_sig);
    sigwait(&mask_sig, &last_sig);
    while(read(*argv[2], &ch, 1) > 0){
        file << ch;
        killpg(0, SIGUSR1);
        sigwait(&mask_sig, &last_sig);
    }
    killpg(0, SIGUSR1);
    file.close();
    return 0;
}

标签: c++linuxfilesignalsexec

解决方案


推荐阅读