1. 獲得本線程ID
pthread_t pthread_self(void)
本函數返回本線程的標識符。
在LinuxThreads中,每個線程都用一個pthread_descr結構來描述,其中包含了線程狀態、線程ID等所有需要的數據結構,此函數的實現就是在線程棧幀中找到本線程的pthread_descr結構,然後返回其中的p_tid項。
pthread_t類型在LinuxThreads中定義爲無符號長整型。
2. 判斷兩個線程是否爲同一線程
int pthread_equal(pthread_t thread1, pthread_t thread2)
判斷兩個線程描述符是否指向同一線程。在LinuxThreads中,線程ID相同的線程必然是同一個線程,因此,這個函數的實現僅僅判斷thread1和thread2是否相等。
3. 僅執行一次的操作
int pthread_once(pthread_once_t *once_control, void (*init_routine) (void))
本函數使用初值爲PTHREAD_ONCE_INIT的once_control變量保證init_routine()函數在本進程執行序列中僅執行一次。
#include <stdio.h>
#include <pthread.h>
pthread_once_t once=PTHREAD_ONCE_INIT;
void once_run(void)
{
printf("once_run in thread %d\n",pthread_self());
}
void * child1(void *arg)
{
int tid=pthread_self();
printf("thread %d enter\n",tid);
pthread_once(&once,once_run);
printf("thread %d returns\n",tid);
}
void * child2(void *arg)
{
int tid=pthread_self();
printf("thread %d enter\n",tid);
pthread_once(&once,once_run);
printf("thread %d returns\n",tid);
}
int main(void)
{
int tid1,tid2;
printf("hello\n");
pthread_create(&tid1,NULL,child1,NULL);
pthread_create(&tid2,NULL,child2,NULL);
sleep(10);
printf("main thread exit\n");
return 0;
}
once_run()函數僅執行一次,且究竟在哪個線程中執行是不定的,儘管pthread_once(&once,once_run)出現在兩個線程中。
LinuxThreads使用互斥鎖和條件變量保證由pthread_once()指定的函數執行且僅執行一次,而once_control則表徵是否執行過。如果once_control的初值不是PTHREAD_ONCE_INIT(LinuxThreads定義爲0),pthread_once()的行爲就會不正常。在LinuxThreads中,實際"一次性函數"的執行狀態有三種:NEVER(0)、IN_PROGRESS(1)、DONE(2),如果once初值設爲1,則由於所有pthread_once()都必須等待其中一個激發"已執行一次"信號,因此所有pthread_once()都會陷入永久的等待中;如果設爲2,則表示該函數已執行過一次,從而所有pthread_once()都會立即返回0。
4. pthread_kill_other_threads_np()
void pthread_kill_other_threads_np(void)
這個函數是LinuxThreads針對本身無法實現的POSIX約定而做的擴展。POSIX要求當進程的某一個線程執行exec*系統調用在進程空間中加載另一個程序時,當前進程的所有線程都應終止。由於LinuxThreads的侷限性,該機制無法在exec中實現,因此要求線程執行exec前手工終止其他所有線程。pthread_kill_other_threads_np()的作用就是這個。
需要注意的是,pthread_kill_other_threads_np()並沒有通過pthread_cancel()來終止線程,而是直接向管理線程發"進程退出"信號,使所有其他線程都結束運行,而不經過Cancel動作,當然也不會執行退出回調函數。儘管LinuxThreads的實驗結果與文檔說明相同,但代碼實現中卻是用的__pthread_sig_cancel信號來kill線程,應該效果與執行pthread_cancel()是一樣的,其中原因目前還不清楚。