每次我的子进程死亡时,我都会尝试调用一个函数。这是通过捕获 execve() 发送的 SIGCHLD 来完成的。我的问题是我的处理函数并不总是被第二次调用。有时是这样,所以我有点困惑。
我的代码是这个:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // sigaction()
#include <time.h>
#include <errno.h>
#include <unistd.h>
#define MAX_LENGTH 1000
#define BILLION 1E9
struct timespec start,stop;
float totalTime = 0;
void runCommand(int signo)
{
printf("Run command called\n");
float processTime = 0;
//Get the time when the process ended
if(clock_gettime(CLOCK_MONOTONIC,&stop) == -1){
perror(NULL);
}
processTime = stop.tv_sec - start.tv_sec + ( stop.tv_nsec - start.tv_nsec ) / BILLION;
totalTime += processTime;
}
int main(int argc, char const *argv[]) {
int counter = 0;
int pid = 0;
int status;
char *args[4];
char line[MAX_LENGTH];
//Setup behaviour for SIGCHLD
struct sigaction psa;
psa.sa_handler = runCommand;
sigaction(SIGCHLD, &psa, NULL);
FILE *fp = fopen("script_file.txt","r");
if(!fp)
{
return 0;
}
//Setup argsgcc
args[0] = "/bin/sh";
args[1] = "-c";
args[3] = NULL;
while(fgets(line, MAX_LENGTH, fp))
{
printf("The command number %d is %s \n", counter, line);
//Get the time when the process started
if(clock_gettime(CLOCK_MONOTONIC,&start) == -1){
perror(NULL);
}
//Create a new process
pid = fork();
//Child process
if(pid == 0)
{
args[2] = line;
execve("/bin/sh", args, NULL);
}
//Parent process
else
{
wait(&status);
}
counter++;
}
printf("The overall time was %f seconds.\n", totalTime);
fclose(fp);
return 0;
}
当我尝试运行它时,有时我的结果是:
The command number 0 is mkdir test/
Run command called
The command number 1 is sleep 0.5
Run command called
The command number 2 is sleep 1
Run command called
The command number 3 is rmdir test/
Run command called
The overall time was 1.544909 seconds.
这似乎是正确的。但在其他情况下,我的结果是:
The command number 0 is mkdir test/
Run command called
The command number 1 is sleep 0.5
The command number 2 is sleep 1
The command number 3 is rmdir test/
The overall time was 0.009810 seconds.
这让我相信 sigaction 并不总是收到我的 SIGCHLD 信号。当我运行 valgrind 时,出现以下错误:
==5407== All heap blocks were freed -- no leaks are possible
==5407==
==5407== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==5407==
==5407== 1 errors in context 1 of 2:
==5407== Syscall param rt_sigaction(act->sa_flags) points to uninitialised byte(s)
==5407== at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==5407== by 0x40098B: main (iv.c:40)
==5407== Address 0xffefff498 is on thread 1's stack
==5407== Uninitialised value was created by a stack allocation
==5407== at 0x400931: main (iv.c:29)
==5407==
==5407==
==5407== 1 errors in context 2 of 2:
==5407== Syscall param rt_sigaction(act->sa_mask) points to uninitialised byte(s)
==5407== at 0x4E6F5AE: __libc_sigaction (sigaction.c:62)
==5407== by 0x40098B: main (iv.c:40)
==5407== Address 0xffefff4a8 is on thread 1's stack
==5407== Uninitialised value was created by a stack allocation
==5407== at 0x400931: main (iv.c:29)
==5407==
==5407== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
但我不确定这意味着什么。