【问题标题】:Signal from parent to its child processes in Linux在 Linux 中从父进程向子进程发送信号
【发布时间】:2019-04-11 02:51:19
【问题描述】:

我将很快写出我想用我的代码做什么以及真正的输出是什么。 我有一个创建两个子进程的父进程。这两个进程中的每一个都从不同的文件中读取 100 个字节,子 1 从“child1.txt”读取,子 2 从“child2.txt”读取。我想通过使用信号强制在孩子 1 之前执行孩子 2。

我创建了两个子进程并暂停了它们(当它们收到信号时暂停结束)。所以我向孩子 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){
}

【问题讨论】:

    标签: c linux unix signals parent-child


    【解决方案1】:

    以下建议的代码::

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 2014-10-08
      • 1970-01-01
      相关资源
      最近更新 更多