2016-10-10 19 views
0

私は2つの子と1つの名前付きパイプ(FIFO)を作成するメインプログラムを持っています。各子はexecv()を介して "sendSignal"というプログラムを実行します。 "sendSignal"の引数の1つはメインプログラムのFIFOです。名前付きパイプで通信する2つの子プロセス

子供たちは互いに信号を送るつもりです。 。。最初のシュートを合図メイン(変数firstShooter中)プログラムでの引数

私はこれらの2人の子供は、この名前付きパイプを介して自分の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

は、あなたの子供プロセスの両方が同じ引数を得た:プロセスは、第1または第2のとしての地位を識別することができないよう

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

firstShooterパラメータは意味がありません。

もう1つのパラメータ - プロセスインデックスを追加することをお勧めします。

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

はあなたが実装されている方法で、いくつかの問題があります:sendSignal機能ロジックは、この方法を変更することができます。 1.メインプログラムで2つのfork()を呼び出すと、2つ以上の子プロセスが作成されます(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. 2つの子プロセスが同じパイプにアクセスしています。パイプは、片方向のコミュニケーションのためのもので、読書の終わりと書込みのためのものです。したがって、プロセスごとに2つのパイプを作成します。私はパイプのために行くことをお勧めしません。

+0

子プロセス( 'if(pid1 == 0)') 'exit(-1);'のように最初の提案は必要ありません。 2)パイプはどのプロセスでも読み書きに使用できますが、唯一の問題はアクセスを正しく同期させることです。 [mkfifo](https://linux.die.net/man/3/mkfifo)のドキュメントを参照してください。 – Nikita

関連する問題