2016-10-04 97 views
2

我在主程序中從父進程創建兩個子進程。第一個和第二個孩子在創建後執行一個程序(signalSender)(與另一個孩子的pid一起作爲參數)。 signalSender具有信號處理程序,用於在進程之間發送信號。當第一個孩子執行signalShooter時,第二個孩子的pid作爲參數給出。當第二個孩子執行sigShooter時,第一個孩子的pid作爲參數給出。兩個子進程之間發送信號

1)我想通過信號處理程序在第二個孩子向第一個孩子發送信號後找到第一個孩子的孩子。我試圖將其保存到全局變量pid_t pid2,但它不起作用。

2)我也必須在這兩個孩子之間發送信號100次,但我不知道在哪裏使用「for循環」和「等待」信號。

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

我認爲你要找的函數是'pause'或'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

是的,它不起作用 –