c-信号处理



我目前正在编写一个函数,用于执行赋值的外部命令。以下是我所做的,问题是程序花费的时间太长,并且被SIGALRM中断。谢谢你的帮助!

volatile sig_atomic_t sig = 0;
void ext(int signum){
if(signum==SIGINT || signum==SIGTERM) sig=1;
}
int extern(char **line){
pid_t p;
int status;
struct sigaction as = {0};
as.sa_handler=ext;
if (sigaction(SIGINT, &as, 0)==-1||sigaction(SIGTERM, &as, 0)==-1){
perror("sigaction");
exit(1);
}
switch(p=fork()){
case -1: perror("fork"); exit(1);
case 0 : if(execvp(line[0], line)<0) {perror("exec"); exit(1);} break;
default : //EDIT 
if(waitpid(p, &status, 0)>=0){
if (WIFEXITED(status)) return WEXITSTATUS(status);  
} else {
perror("wait");
exit(1);
}
break;
}
return 0;
}

信号处理不会在对execve的调用中进行。一旦execvp执行,它们就会被重置。

即使信号在执行execpv之前到达子进程,父进程和子进程也有自己的副本

volatile sig_atomic_t sig = 0;

子级中的信号处理程序更改此值不会导致父级的副本发生更改。

在这里,建立信号处理程序不是正确的方法。

相反,使用waitpid的方法是正确的,但除了使用WIFEXITED(status)检查程序是否正常终止外,还应该包括另一个检查WIFSIGNALED(status)的分支,如果子进程因信号而终止,则此分支将为真。

CCD_ 7用于确定哪个信号终止了子进程。

下面是一个一般的例子,其中子进程随机成功退出,或者以其他方式发出默认处理是终止程序的信号:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
int main(void)
{
pid_t child = fork();
if (-1 == child) {
perror("fork");
return EXIT_FAILURE;
}
if (0 == child) {
/* randomly signal or return successfully */
srand((unsigned) time(NULL));
switch (rand() % 4) {
case 1: raise(SIGINT); break;
case 2: raise(SIGTERM); break;
case 3: raise(SIGKILL); break;
}
return EXIT_SUCCESS;
}
int status;
if (-1 == waitpid(child, &status, 0)) {
perror("wait");
return EXIT_FAILURE;
}
if (WIFSIGNALED(status)) {
int sig = WTERMSIG(status);
if (SIGINT == sig || SIGTERM == sig)
printf("Child <%ld> exited by signal SIGINT or SIGTERM.n", (long) child);
else
printf("Child <%ld> exited by signal #%d.n", (long) child, sig);
} else if (WIFEXITED(status)) {
printf("Child <%ld> exited normally with status %d.n",
(long) child,
WEXITSTATUS(status));
}
}

运行此程序几次的输出:

Child <41268> exited by signal SIGINT or SIGTERM.
Child <41272> exited by signal SIGINT or SIGTERM.
Child <41276> exited by signal #9.
Child <41280> exited normally with status 0.

最新更新