2012-02-17 43 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信號屬於第二類,並且正在爲該過程生成。