0

Revisiting this question:

I have multiple threads running (pthreads api), each with it's own timer that calls a function handler(int signum) after a certain interval. As these threads call handler and within the function handler, how do I know which thread called it? Is thread-specific data required?

I notice that the thread that enters the handler function is a different thread from the one that set it up, so calling pthread_self() doesn't work. How do I get around this?

Here is a small example illustrating the problem

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>

void handler(int);
void call_alarm();
void *setup(void*);

pthread_t p;

void handler(int signum)
{
    printf("handler thread %lu\n", pthread_self());
}

void call_alarm()
{   
    static struct itimerval timer;
    static struct sigaction sa;

    printf("call_alarm %lu\n", (unsigned long)pthread_self());

    sa.sa_handler = handler;
    sa.sa_flags = SA_RESETHAND;
    timer.it_value.tv_usec = 500;
    timer.it_value.tv_sec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;

    sigaction(SIGALRM, &sa, 0);
    setitimer(ITIMER_REAL, &timer, 0);
}

void *setup(void *param)
{
    while(1)
    {
        printf("caller thread %lu\n", pthread_self());
        call_alarm();
        pause();
    }
}

int main(void)
{
    if(pthread_create(&p, NULL, setup, NULL));
    while(1);
    return 0;
}

Output:

caller thread 3086637968
call_alarm 3086637968
handler thread 3086640832

As you can see it prints out different values.

Lucas
  • 1,577
  • 6
  • 18
  • 25

2 Answers2

1

You can print the thread ID when the handler is called:

and if you can't, write a function wrapper around the handler and tell your code to call the wrapper function instead of calling the handler directly.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • 1
    +1. More on [`gettid` vs `pthread_self`](http://stackoverflow.com/a/6372351/298054). – jweyrich Feb 17 '12 at 21:55
  • This isn't answering the original question. Should I use the current implementation of timer. I just want to know which thread called the handler using pthreads. – Lucas Feb 17 '12 at 22:12
0

The POSIX chapter on Signal Generation and Delivery states:

At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. Signals that are generated in association with a process ID or process group ID or an asynchronous event, such as terminal activity, shall be generated for the process.

I wonder if the SIGALRM signal you're catching is not considered a action attributable to a particular thread, such as a hardware fault. It sounds like your SIGALRM signal falls into the second category, and is being generated for the process.

sholsapp
  • 15,542
  • 10
  • 50
  • 67