I have a parent process that created 16 child processes using fork in a loop. Eventually, every child sends a SIGUSR1 signal , that is handled by a handler function in the parent process.
My problem is this - some children send the signal while a signal from another child is handled. I read that the handler function then stops and handles the new signal, ignoring the current signal its working on.
I tried to fix that by sending: kill(0,SIGSTOP)
at the start of the handler function, but looks like that stops the parent process as well. Is there a way to send this signal only to the children?
If its not possible, is my goal achievable using wait, waitpid and kill
?
Added the code below, I left out stuff like checking the return value for read, open etc.
Handler function:
void my_signal_handler( int signum, siginfo_t* info, void* ptr)
{
kill(0, SIGSTOP);
int sonPid = info->si_pid;
char* pipeName = malloc(14 + sizeof(int));//TODO ok?
sprintf(pipeName, "//tmp//counter_%d" , (int) sonPid); //TODO double //?
size_t fdPipe = open(pipeName, O_RDONLY);
int cRead;
int countRead = read(fdPipe,&cRead,sizeof(int));
COUNT+= cRead;
kill(0, SIGCONT);
return;
}
Creating the child processes:
struct sigaction new_action;
memset(&new_action, 0, sizeof(new_action));
new_action.sa_handler = my_signal_handler;
new_action.sa_flags = SA_SIGINFO;
if( 0 != sigaction(SIGUSR1, &new_action, NULL) )
{
printf("Signal handle registration failed. %s\n", strerror(errno));
return -1;
}
for(int i=0; i<16; i++){
pid_t cpid = fork();
if(cpid == 0) // child
{
execv("./counter",argvv); // some arguments to the function
printf("execv failed: %s\n", strerror(errno));
return -1;
}
else{
continue;
}
The counter program of the children, in short it counts the appearances of the char counc
in some part of the file then prints it to a pipe.:
int main(int argc, char** argv){
int counter = 0;
char counc = argv[1][0];
char* filename = argv[2];
off_t offset = atoll(argv[3]);
ssize_t length = atoll(argv[4]);
int fd = open(filename, O_RDWR | O_CREAT);
char* arr = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
for(int i=0; i<length; i++){
if(arr[i] == counc){
counter++;
}
}
pid_t proid = getpid();
pid_t ppid = getppid();
char* pipeName = malloc(14 + sizeof(pid_t));
sprintf(pipeName, "//tmp//counter_%d" , (int) proid);
size_t fdPipe = mkfifo(pipeName, 0777);
int didopen = open(pipeName,O_WRONLY);
size_t wrote = write(fdPipe,&counter , 1 );
if(wrote < 0){
printf(OP_ERR, strerror( errno ));
return errno;
}
kill(ppid, SIGUSR1);
//close the pipe and unmap the array
return 1;
}