2012-02-17 44 views
0

再谈这个问题:指示哪个线程设置了定时器处理程序?

我有运行(并行线程API)多线程,每个都有它自己的计时器调用一定的时间间隔后的函数处理程序(INT正负号)。当这些线程调用处理函数并在函数处理函数中时,我怎么知道哪个线程调用了它?是否需要线程特定的数据?

我注意到,进入处理函数的线程与设置它的线程不同,所以调用pthread_self()不起作用。我如何解决这个问题?

这里是示出

#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; 
} 

输出该问题的一个小例子:

caller thread 3086637968 
call_alarm 3086637968 
handler thread 3086640832 

正如你可以看到它打印出不同的值。

回答

1

可以打印线程ID时的处理程序被调用:

如果不能,请在处理程序周围写一个函数包装,并告诉你的代码调用包装函数而不是直接调用处理程序。

+1

+1。更多关于['gettid'和'pthread_self'](http://stackoverflow.com/a/6372351/298054)。 – jweyrich 2012-02-17 21:55:36

+0

这不是回答原来的问题。我应该使用当前的计时器实现吗?我只是想知道哪个线程使用pthreads调用处理程序。 – Lucas 2012-02-17 22:12:11

0

POSIX chapter on Signal Generation and Delivery状态:

在生成时,应做出的确定是否在信号已用于过程或过程中的一特定线程生成。应该为引起信号产生的线程产生由可归因于特定线程的某些动作产生的信号,例如硬件故障。应为过程生成与进程ID或进程组ID或异步事件(如终端活动)关联生成的信号。

我不知道,如果你赶上了SIGALRM信号不被认为是动作归因于特定线程,如硬件故障。这听起来像是您的SIGALRM信号属于第二类,并且正在为该过程生成。