2016-10-10 119 views
0

我有創建兩個子進程和一個命名管道(FIFO)的主程序。每個孩子通過execv()執行一個叫做「sendSignal」的程序,其中一個參數是主程序中的FIFO。爭論在main(可變firstShooter)程序,信號先開槍兩個子進程通過命名管道進行通信

我想知道如何這兩個孩子可以互相發送自己的PID通過這個命名管道

下面是主要程序:。

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

/* this program should be provided with 2 arguments */ 

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

    char str1[15]; 
    char str2[15]; 
    char fileDescriptor[15]; 
    char *my_args[4]; 
    char *myfifo = "myfifo"; 

    int fd, pipeCheck; 
    pid_t pid1, pid2, wid; 


    /* If the user does not provide the argument to determin which child is firing first */ 
    if(argc != 2) 
    { 
    fprintf(stderr,"%s: 2 arguments needed, got %d\n",argv[0],argc-1); 
    exit(1); 
    } 

    /* create the FIFO (named pipe) */ 
    pipeCheck = mkfifo(myfifo, 0666); 

    /* check if the named pipe was created properly if not output an error */ 
    if(pipeCheck == -1) 
    { 
    fprintf(stderr, "%s: Error creating named pipe: %s\n",argv[0], strerror(errno)); 
     exit(1);  
    } 


    pid1 = fork(); 

    if (pid1 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 
     exit(1); 
    } 

    if(pid1 == 0) 
    { 


     my_args[0] = "sendSignal"; 
     my_args[1] = argv[1]; 
     my_args[2] = myfifo; // the named pipe as arguemnt 
     my_args[3] = NULL; 
     execv("sendSignal",my_args); 
     fprintf(stderr,"sendSignal cannot be executed by first child..."); 
     exit(-1); 
    } 


    pid2 = fork(); 

    if(pid2 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 
     exit(1); 
    } 

    if(pid2 == 0) 
    { 

     my_args[0] = "sendSignal"; 
     my_args[1] = argv[1]; 
     my_args[2] = myfifo; // named pipe as arguemnt 
     my_args[3] = NULL; 
    // printf("this is converted = %s\n",my_args[1]); 
     execv("sendSignal",my_args); 
     fprintf(stderr,"sendSignal cannot be executed by second child..."); 
     exit(-1); 
    } 

close(fd); 
unlink(myfifo); 


wid = wait(NULL); 


return 0; 

} 

這裏是sendSignal:

你的孩子的過程中
#include <sys/types.h> 
#include <sys/wait.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <signal.h> 


void sig_handler(int signo) 
{ 
    if(signo == SIGUSR1) 
     printf("signal received\n"); 

} 

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

    char abspath[256] = ""; 
    getcwd(abspath, 256); 
    strrchr(abspath, '/'); 

    if(signal(SIGUSR1,sig_handler) == SIG_ERR) 
     printf("\n Cannot catch the signal\n"); 

    char *myfifo = "myfifo"; 

    int firstShooter = atoi(argv[1]); //define the first process to send the signal 

    int fd; 
    char str1[15]; 
    char str2[15]; 
    char pid1[15]; 
    char pid2[15]; 

    fd = open(argv[2],O_RDWR); 


    if(firstShooter == 1) 
    { 
     sprintf(pid1,"%d",getpid()); 
     write(fd,pid1,sizeof(pid1)); 
    } 

    if(firstShooter == 2) 
    { 
     sprintf(pid2,"%d",getpid()); 
     write(fd,pid2,sizeof(pid2)); 
    } 


    read(fd,str1,sizeof(str2)); 
    read(fd,str2,sizeof(str2)); 

    close(fd); 

    printf("str1 = %s\n",str1); 
    printf("str2 = %s\n",str2); 


    return 0; 
} 

回答

0

都得到了相同的論點:

my_args[0] = "sendSignal"; 
my_args[1] = argv[1]; 
my_args[2] = myfifo; // the named pipe as argument 
my_args[3] = NULL; 

firstShooter參數沒有任何意義,因爲過程本身不能識別作爲第一或第二。

我建議增加一個參數 - 進程索引。 sendSignal功能邏輯可以修改這種方式:

char pid1[15]; 
char pid2[15]; 
int processIndex = atoi(argv[3]); 

fd = open(argv[2],O_RDWR); 

if (processIndex == firstShooter) 
{ 
    // Send firstShooter PID 
    sprintf(pid1,"%d",getpid()); 
    write(fd,pid1,sizeof(pid1)); 

    // Got the other PID 
    read(fd,pid2,sizeof(pid2)); 
} 
else 
{ 
    // Got the firstShooter PID 
    read(fd,pid1,sizeof(pid1)); 

    // Send the other PID 
    sprintf(pid2,"%d",getpid()); 
    write(fd, pid2, sizeof(pid2)); 
} 

close(fd); 

printf("pid1 = %s\n",pid1); 
printf("pid2 = %s\n",pid2); 
0

有你已經實現了這樣的一些問題。 1.在主程序中調用兩個fork()將創建兩個以上的子進程(3個子進程)。因此給出一個條件來檢查你是否正在調用父類本身上下文中的下一個分支。

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

/* this program should be provided with 2 arguments */ 

int main(int argc, char **argv) 
{ 
    int * status; 
    char str1[15]; 
    char str2[15]; 
    char fileDescriptor[15]; 
    char *my_args[4]; 
    char *myfifo = "myfifo"; 

    int fd, pipeCheck; 
    pid_t pid1, pid2, wid; 


    /* If the user does not provide the argument to determin which child is firing first */ 
    if(argc != 2) 
    { 
     fprintf(stderr,"%s: 2 arguments needed, got %d\n",argv[0],argc-1); 
     exit(1); 
    } 

    /* create the FIFO (named pipe) */ 
    pipeCheck = mkfifo(myfifo, 0666); 

    /* check if the named pipe was created properly if not output an error */ 
    if(pipeCheck == -1) 
    { 
     fprintf(stderr, "%s: Error creating named pipe: %s\n",argv[0], strerror(errno)); 
     exit(1);  
    } 


    pid1 = fork(); 

    if (pid1 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 
     exit(1); 
    } 

    if(pid1 == 0)//child 
    { 
// printf("pid1=0\n"); 
     printf("i am child 1 %d\n",getpid()); 
     my_args[0] = "sendSignal"; 
     my_args[1]=malloc(6); 
     sprintf(my_args[1] , "%d", getpid()); 
     //my_args[1]="1"; 
     printf("p%s\n",my_args[1]); 
     my_args[2] = myfifo; // the named pipe as arguemnt 
     my_args[3] ="1"; 
     execv("sendSignal",my_args); 
     fprintf(stderr,"sendSignal cannot be executed by first child..."); 
     exit(-1); 
    } 
    else if(pid1>0)// parent 
    { 
     // printf("pid1 %d",pid1); 
     waitpid(pid1,&status,WIFEXITED(status)); 
     pid2 = fork(); 
     // printf("p:%d",pid2); 
    if(pid2 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 
     exit(1); 
    } 
    if(pid2 == 0) 
    { 
     printf("i am child 2 %d\n",getpid()); 
     my_args[0] = "sendSignal"; 
     my_args[1]=malloc(6); 
     sprintf(my_args[1] , "%d", getpid()); 
     my_args[2] = myfifo; // named pipe as arguemnt 
     my_args[3] = "2"; 
     // printf("this is converted = %s\n",my_args[1]); 
     execv("sendSignal",my_args); 
     fprintf(stderr,"sendSignal cannot be executed by second child..."); 
     exit(-1); 
    } 
    printf("done\n"); 
    } 

close(fd); 
wait(NULL); 
fd=open("fifo1", O_RDONLY); 
char * space=(char *)malloc(6); 
read(fd,space,6); 
printf("from fifo1 %s",space); 

fd=open("fifo2", O_RDONLY); 
//char * space=(char *)malloc(6); 
read(fd,space,6); 
printf("from fifo2 %s",space); 
//unlink(myfifo); 


wid = wait(NULL); 
unlink(myfifo); 

return 0; 

} 

2.兩個子進程正在訪問相同的管道。 Pipe是單向通信,一端用於閱讀,另一端用於書寫。因此,爲每個進程創建兩個管道。我建議最好不要去管道。

+0

第一個建議是不需要的,因爲在子進程('if(pid1 == 0)')'exit(-1);'將被執行。 2)管道可以用於任何進程的讀/寫,唯一的問題是正確同步訪問。在[mkfifo](https://linux.die.net/man/3/mkfifo)文檔中詳細瞭解它。 – Nikita

相關問題