Сигнал от родителя к его дочерним процессам в Linux - PullRequest
0 голосов
/ 07 ноября 2018

Я напишу в ближайшее время, что я хочу сделать с моим кодом и каков реальный результат. У меня есть родительский процесс, который создает два дочерних процесса. Каждый из двух процессов читает по 100 байт из другого файла, дочерний элемент 1 читается из «child1.txt», дочерний 2 читается из «child2.txt». Я хочу заставить казнить ребенка 2 перед ребенком 1 с помощью сигналов.

Я создал два дочерних процесса и приостановил их (пауза заканчивается, когда они получают сигнал). Итак, я отправил сигнал ребенку 2, а затем отправил сигнал ребенку 1. Таким образом, я ожидаю, что они будут делать то, что я хочу, но они этого не делают (это всегда показывает содержание child1.txt), и я не понимаю почему.

Это код

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

void my_handler(int signo);

int main(int argc, char *argv[]){
    signal(SIGCHLD,my_handler);
    pid_t pid[2]; //here is where I save child pid
    char buffer[100];
    for (int i=0;i<2;i++){
        if((pid[i]=fork())==0){
            signal(SIGUSR1,my_handler);
            int fd,nbyte;
            pause();
            if(i==0){
                fd=open("Child1.txt",O_RDONLY);
            }else{
                fd=open("Child2.txt",O_RDONLY);
            }
            nbyte=read(fd,buffer,100);
            buffer[nbyte-1]='\0';
            write(STDOUT_FILENO,buffer,strlen(buffer));
            exit(1);
        }
        sprintf(buffer,"Child %d\n",(int)pid[i]);
        write(STDOUT_FILENO,buffer,strlen(buffer));
    }
    kill(pid[1],SIGUSR1); //I send a signal to unpause child2
    wait(NULL); // wait child 2 to terminate
    kill(pid[0],SIGUSR1); //unpause child 1
    wait(NULL); // wait child 1 to terminate

}


void my_handler(int signo){
}

1 Ответ

0 голосов
/ 07 ноября 2018

следующий предложенный код ::

  1. чисто компилирует
  2. выполняет желаемую функциональность
  3. правильно проверяет наличие ошибок
  4. использует правильную типизацию переменных
  5. устраняет «магические» числа, давая им осмысленные имена

и теперь предложенный код:

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


#define BUF_SIZE     100
#define NUM_CHILDREN 2


void my_handler(int signo);

int main( void )
{
    //signal(SIGCHLD,my_handler);
    pid_t pid[ NUM_CHILDREN ] = {0};
    char buffer[ BUF_SIZE +1];

    for ( int i=0; i<NUM_CHILDREN; i++ )
    {
        if((pid[i]=fork())==0)
        { // then child
            signal(SIGUSR1,my_handler);
            int fd;
            ssize_t nbyte;
            pause();

            if(i==0)
            {
                if( (fd=open("child1.txt",O_RDONLY) ) == -1 )
                {
                    perror( "open to read child1.txt failed" );
                    exit( EXIT_FAILURE );
                }
            }

            else
            {
                if( (fd=open("child2.txt",O_RDONLY) ) == -1 )
                {
                    perror( "open to read child2.txt failed" );
                    exit( EXIT_FAILURE );
                }
            }

            if( (nbyte=read(fd,buffer,100) ) ==-1 || nbyte == 0 )
            {
                perror( "read failed" );
                exit( EXIT_FAILURE );
            }

            buffer[nbyte]='\0';

            write(STDOUT_FILENO,buffer,strlen(buffer));
            fflush( stdout );
            close( fd ); 

            exit( EXIT_SUCCESS );
        }

        else if( pid[i] > 0 )
        { // then parent 
            sprintf( buffer,"Child %d PID %d\n", i, (int)pid[i] );
            write( STDOUT_FILENO, buffer, strlen(buffer) );
            fflush( stdout );
        }

        else
        { // fork failed
            perror( "fork failed" );
        }
    }

    sleep(1);  // allow all child processes to be ready for signal

    if( pid[0] > 0 )
    {
        kill(pid[0],SIGUSR1); //send a signal to unpause child 0
        wait( NULL ); 
    }

    if( pid[1] >  0 )
    {
        kill(pid[1],SIGUSR1); //unpause child 1
        wait( NULL ); 
    }
}


void my_handler(int signo)
{
    (void)signo;
}

содержимое child1.txt (обратите внимание, что я использовал строчные буквы для имени файла)

123

содержимое child2.txt (обратите внимание, что я использовал строчные буквы для имени файла)

456

выполнение кода приводит к:

Child 0 6630
Child 1 6631
123

456
...