Как использовать задержку сигнала с помощью sigwait()

#c #linux #signals #clion

#c #linux #сигналы #клион

Вопрос:

при назначении мне нужно написать программу, которая открывает канал канала и вызывает два процесса-потомка, а затем родительский заполняет канал из входного файла, а затем отправляет сигнал SIGQUIT потомкам, которые могут считывать символы из канала и отправлять друг другу сигналы после считывания следующего символа SIGUSR1 иSIGUSR2 для того, чтобы другой потомок смог начать чтение, но возникла проблема: в цикле чтения родительский элемент находится в ступоре, и если debajo шаги, то все нормально, и он выходит из цикла, или если чистые строки exec, то происходит выход из цикла. Я не понимаю, в чем может быть проблема. В потомках я использую sigwait для ожидания. Я представлю коды родительского и потомков ниже. Пожалуйста, скажите мне, что не так? Код родительского:

 #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(amp;new_mask);
    sigaddset(amp;new_mask, SIGUSR1);
    sigaddset(amp;new_mask, SIGUSR2);
    sigaddset(amp;new_mask, SIGQUIT);
    sigprocmask(SIG_SETMASK, amp;new_mask, NULL);
    int fildes[2];
    pipe(fildes);
    pid_t pid1;
    pid_t pid2;
    pid1 = fork();
    if (pid1 == 0) {
        //execl("1","1", "output1.txt", amp;fildes[0], amp;fildes[1],NULL);
        close(fildes[0]);
        _exit(0);
    }
    else {
        pid2 = fork();
        if (pid2 == 0) {
            execl("2","2", "output2.txt", amp;fildes[0], amp;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;
                bool t = true;
                t = (bool)getline(file, str);
                while(t){
                    write(fildes[1], amp;str[0], strlen(str.c_str()));
                    cout<<"PARENT пишет:" << str << endl;
                    cout<< "sdsdsds";
                    t = (bool)getline(file, str);
                }
                cout << "aaaaaaaaaaaaaaaaaaaaaaaaa";
                killpg(0, SIGQUIT);
                file.close();
            }
            int st1, st2;
            waitpid(pid1, amp;st1, 0);
            waitpid(pid2, amp;st2, 0);
            close(fildes[1]);
            exit(EXIT_SUCCESS);

        }
    }

    return 0;
}
 

Первый дочерний код:

 #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) {
    int fildes[2];
    fildes[0]=*argv[2];
    fildes[1]=*argv[3];
    close(fildes[1]);
    sigset_t mask_sig;
    sigemptyset(amp;mask_sig);
    sigaddset(amp;mask_sig, SIGUSR1);
    sigaddset(amp;mask_sig, SIGQUIT);
    ofstream file;
    int last_sig;
    char ch;
    file.open(argv[1], ios::app);
    //file << read(fildes[0], amp;ch, 1)  << endl;
    sigwait(amp;mask_sig, amp;last_sig);
    while(read(fildes[0], amp;ch, 1) > 0){
        //file << "a" << endl;
        file << ch;
        killpg(0, SIGUSR2);
        sigwait(amp;mask_sig, amp;last_sig);
    }
    killpg(0, SIGUSR2);
    file.close();
    return 0;
}
 

Второй дочерний код:

 #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) {
    int fildes[2];
    fildes[0]=*argv[2];
    fildes[1]=*argv[3];
    close(fildes[1]);
    sigset_t mask;
    sigemptyset(amp;mask);
    sigaddset(amp;mask, SIGQUIT);
    sigset_t mask_sig;
    sigemptyset(amp;mask_sig);
    sigaddset(amp;mask_sig, SIGUSR2);
    ofstream file;
    int last_sig;
    char ch;
    file.open(argv[1], ios::app);
    //sigwait(amp;mask, amp;last_sig);
    sigwait(amp;mask_sig, amp;last_sig);
    while(read(fildes[0], amp;ch, 1) > 0){
        file << ch;
        killpg(0, SIGUSR1);
        sigwait(amp;mask_sig, amp;last_sig);
    }
    killpg(0, SIGUSR1);
    file.close();
    return 0;
}
 

Комментарии:

1. «но была проблема: в цикле чтение родительского элемента вызывает ступор» — я не понимаю такого описания проблемы. Вы имеете в виду, что родительский процесс блокируется при write(fildes[1], amp;str[0], strlen(str.c_str())); вызове? Или что?

2. @Tsyvarev он заблокировался после cout<<«PARENT пишет:» << str << endl;, когда последняя строка была прочитана из входного файла, но без exec она работала нормально