bittersweets bittersweets - 10 months ago 53
C Question

Signal receiver threads in C and pthread_join stalling program

I'm trying to build a basic program which has 2/3 threads. The main thread, signaler thread, and receiver thread. I'm trying to make it so the main thread starts both a signaler and receiver thread. The signaler thread is then supposed to send 10 SIGUSR1 signals to the receiver thread and increase a global counter. The receiver thread is supposed to receive the 10 signals while increasing its own counter for each signal received.

The trouble I'm having is with joining the threads back together at the end, specifically joining the receiver thread. The majority of the time the program stalls if I try to join them back together, I assume because the receiver thread hasn't finished its job (maybe it has missed signals?) and so it never finishes. I thought maybe this was the case, so I introduced a wait command in the signaler thread to slow it down, but that didn't change anything.

If I comment out the pthread_join(receiver, NULL) then the program runs, but it only catches one signal most of the time. I assume this is because the receiver thread isn't getting much time to run. (although sometimes it catches various amounts, depending on when it was preempted?)

Leaving the pthread_join(receiver, NULL) in the program makes it stall 19/20 times, but that 1/20 time the program returns 10 signals sent and 10 received. This leads me to believe it has something to do with preemption, but I don't understand why it would ever stall in the first place.

Also right now I just have the receiver thread receiving threads while the received counter is < 10. Ideally I would just want to leave it in while(1) loop, but then again I don't know how to join that back into the main thread without freezing everything.

If someone could help me figure out why signals are being missed / why the program is freezing I would be most grateful. I have a suspicion that I'm not setting up the signal mask correctly for the receiver, but I don't know how else I am supposed to do it. Here is the code:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>

void *receivetest(void *args);
void *signaltest(void *args);

int received = 0;
int sent = 0;
pthread_t signaler;
pthread_t receiver;
sigset_t mask;

int main(){

//setting up the signal mask
sigaddset(&mask, SIGUSR1);

//creation of both threads
pthread_create(&receiver, NULL, receivetest, NULL);
pthread_create(&signaler, NULL, signaltest, NULL);

pthread_join(signaler, NULL);
pthread_join(receiver, NULL);

//printing results after joining them back
printf("I'm the main function\n");
printf("Receieved: %d, sent: %d\n", received, sent);


void *signaltest(void *args){
int i = 0;
for(i=0;i<10;i++){ //sends 10 signals to receiver thread
pthread_kill(receiver, SIGUSR1);

void *receivetest(void *args){
int c; //sigwait needs int
pthread_sigmask(SIG_BLOCK, &mask, NULL); //sets up the signal mask for this thread
while(received < 10){ //waits for 10 signals and increments receieved
sigwait(&mask, &c);

Answer Source

Signals just don't work that way. If a thread receives a signal while that same signal is already pending, nothing happens. Please use an appropriate inter-thread communication method, not signals.