2016-10-04 1 views
2

주 프로그램의 부모로부터 두 명의 자식을 만듭니다. 첫 번째와 두 번째 자식은 생성 된 후 (다른 자식의 PID와 함께) 프로그램을 실행합니다 (signalSender). signalSender는 시그널 핸들러를 가지고 있으며 프로세스간에 시그널을 보내기 위해 사용됩니다. 첫 번째 자식이 signalShooter를 실행할 때 두 번째 자식의 PID는 인수로 0으로 지정됩니다. 두 번째 자식이 sigShooter를 실행할 때 첫 번째 자식의 pid가 인수로 제공됩니다.두 자식 프로세스간에 신호를 전송합니다.

1) 두 번째 자식이 첫 번째 자식에게 신호를 보낸 후 신호 처리기를 통해 첫 번째 자식의 PID를 찾고 싶습니다. 전역 변수 pid_t pid2에 저장하려고했지만 작동하지 않습니다.

2) 나는이 두 아이 사이의 신호를 100 번 보내야하지만 어디에서 'for loop'와 'wait'신호를 사용해야하는지 잘 모릅니다.

The main program: 

#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> 

int main() 
{ 
    pid_t pid1,pid2,wid; 
    char *my_args[5]; 
    int aInt = 368 
    char str[15]; 
    pid1 = fork(); 
     if (pid1 < 0) 
    { 
     fprintf(stderr, ": fork failed: %s\n", strerror(errno)); 

     exit(1); 

    } 
    if(pid1 == 0) 
    { 
     my_args[0] = "sigperf1"; 
     my_args[1] = "0"; 
     my_args[2] = NULL; 
     execv("signalSender",my_args); 
     fprintf(stderr,"signalSender cannot be executed..."); 
     exit(-1); 
    } 

    pid2 = fork(); 

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

    if(pid2 == 0) 
    { 
     sprintf(str, "%d", pid1); 
     my_args[0] = "sigperf1"; 
     my_args[1] = str; 
     my_args[2] = NULL; 
    // printf("this is converted = %s\n",my_args[1]); 
     execv(“signalSender",my_args); 
     fprintf(stderr,"signalSender cannot be executed..."); 
     exit(-1); 
    } 
wid = wait(NULL); 

} 

signalSender :

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

pid_t pid2; 
struct sigaction act; 

void sighandler(int signum, siginfo_t *info, void *ptr) 
{ 
    printf("Received signal %d\n", signum); 
    printf("Signal originates from process %lu\n", 
     (unsigned long)info->si_pid); 
     pid2 = info->si_pid; 
} 

int main(int argc,char **argv) 
{ 
    memset(&act, 0, sizeof(act)); 
    act.sa_sigaction = sighandler; 
    act.sa_flags = SA_SIGINFO; 
    sigaction(SIGUSR1, &act, NULL); 

    pid_t current, pidOther; 
    current = getpid(); 
    pidOther = atol(argv[1]); 

    if(pidOther != 0) // we are in the second child 
    { 
     kill(pidOther,SIGUSR1); //sending signal from second child to first 
    } 

    if(pidOther == 0) // we are in the first child 
    { 
     kill(pid2,SIGUSR1); 
    } 

    return 0; 
} 
+0

찾고있는 기능이 '일시 중지'또는 'sigsuspend'라고 생각합니다. – user3386109

답변

0

당신은 여기에 동기화 문제가 있습니다.

두 자식 프로세스는 거의 동시에 시작됩니다. 그래서 어느 것이 먼저 kill 다른 하나를 예측할 수 없습니다. 첫 번째 자식이 kill을 먼저 실행하면 0이 pid로 전달되어 프로세스 그룹의 모든 프로세스가 종료됩니다. 또한 각 하위 프로세스는 kill을 호출 한 직후 종료되므로 다른 자식 프로세스가 신호를 보낼 기회가 있기 전에 종료 될 수 있습니다.

몇 가지 유형의 동기화 방법을 소개해야합니다. 이를 수행하는 간단한 방법은 kill을 호출하기 전에 잠시 후에 두 번째 프로세스 sleep을 시작하여 첫 번째 프로세스에 시작할 수있는 기회를 제공하는 것입니다. 마찬가지로 첫 번째 프로세스는 pause을 호출해야 신호를 수신 할 때까지 기다려야합니다.

이렇게하면 각 프로세스에서 pausekill을 반복적으로 호출하여 앞뒤로 이동할 수 있습니다.

if(pidOther != 0) // we are in the second child 
{ 
    sleep(1); // wait for first child to start 
    kill(pidOther,SIGUSR1); //sending signal from second child to first 
    for (i=0;i<5;i++) { 
     pause(); 
     kill(pidOther,SIGUSR1); 
    } 
} 

if(pidOther == 0) // we are in the first child 
{ 
    pause(); // wait until we get a signal from the second child 
    kill(pid2,SIGUSR1); 
    for (i=0;i<5;i++) { 
     pause(); 
     kill(pid2,SIGUSR1); 
    } 
} 
+1

좋은 분석이지만 ... 수면은 석고처럼 보입니다. 확실하게 보장 된 동기화가 보장되어야합니까? 우리가 진정으로 문제에 대해 진정으로 대답하고 있는지 확신 할 수 없습니다. – Joe

+0

예 작동하지 않습니다. –

관련 문제