2012-11-12 69 views
1

我正在編寫一個簡單的shell,並且我必須使用execv將子進程分叉到外部程序。我必須將信號TSTP(Cntl + Z)發送到信號處理程序,然後終止當前正在運行的子進程。我的問題是我找不到一種方法將Child pid傳遞給信號處理程序。如果我在處理程序中執行getpid(),它只是返回父pid。我也嘗試在孩子進程中設置孩子pid爲getpid(),並將該變量設置爲全局變量,但這也不起作用。這是我迄今爲止的一些代碼。從信號處理程序中殺死子進程

void handler(int); 
//in main 
if (!built_in_cmd(myArgc,myArgs)) { 
    pid_t pid; 
    char *x = myArgs[0]; 
    if((pid=fork())<0) 
     printf("Parent: fork() process failed"); 
    else { 
     if (pid == 0) { 
      y=getpid(); 
      printf("Parent: My child has been spawned. %d %d\n",y,getppid()); 
      execv(x, myArgs); 
      exit(0); 
     } 
     else { 
      signal(SIGTSTP,handler); 
      wait(0); 
      printf("Parent: My child has terminated.\n"); 
     } 
    } 
} 
return; 

//outside main 
void handler(int signo){ 
    kill(idk,SIGKILL); 
} 
+0

'fork()'返回子PID。把它放在一個全局變量中,並在信號處理程序中使用它。 – Barmar

+1

順便說一句,你的路線「父母:我的孩子已經產卵」是由孩子打印的,而不是父母的聲稱。 – Barmar

回答

4

信號在本質上是異步的,除了通過全局變量,沒有辦法將任何額外的狀態傳遞給它們。假設你只有一個線程在等待孩子,那麼使用全局變量是安全的,否則沒有多線程安全的方式:

// At global scope 
pid_t child_pid = (pid_t)-1; 
... 
void myfunc() 
{ 
    pid_t pid; 
    if((pid = fork()) < 0) 
     ... 
    else if(pid == 0) 
     ... 
    else 
    { 
     child_pid = pid; 
     ... 
    } 
} 
+1

不完全正確,您不能將額外狀態傳遞給信號處理程序。當然,使用全局變量是最簡單的事情,但您可以將pid(和任意任意數據)寫入管道並在信號處理程序中讀取它。 –