2012-11-12 70 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(和任意任意数据)写入管道并在信号处理程序中读取它。 –