2015-12-19 39 views
4

該引用來自man page of pthread_self()pthread_self()返回的線程標識與調用gettid(2)返回的內核線程標識不同(012)

那麼,憑什麼要我決定我是否應該使用pthread_selfgettid以確定哪個線程運行的功能?

兩者都不可攜帶。
爲什麼有兩個不同的函數來獲取線程ID?

+0

因爲Linux的線程是kludgy。 – James

+2

['pthread_self'](http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_self.html)函數非常便攜,[[POSIX]]中的「P」(https:// en。畢竟,wikipedia.org/wiki/POSIX代表* Portable *。 –

回答

8

那麼,我應該在什麼基礎上決定是使用pthread_self還是使用 gettid來確定哪個線程正在運行該函數?

無論何時您想要在您的應用程序中標識線程,您都應該始終使用pthread_self()gettid()可以是用於某些目的如果你知道它是Linux。例如,gettid()可用於獲取特定於線程的種子的種子(用於srand())。

兩者都不可攜帶。

這個我不完全是真的。由於其特定於Linux的功能,因此不能將其移植到其他產品中。但pthread_self()是便攜式的,只要您不對其表示做任何假設。

例如,以下是不是便攜式。

printf("Thread ID is: %ld", (long) pthread_self()); 

,因爲沒有保證,無論pthread_self()將是某種形式的整數。但是

pthread_t my_tid; //filled elsewhere 

pthread_t tid = pthread_self(); 

if(pthread_equal(my_tid, tid)) { 
    /* do stuff */ 
} 

是完全便攜的。

前者不便攜,因爲它假定線程id是一個整數,而後者不是。

爲什麼有兩種不同的函數來獲取線程ID?

他們沒有兩種不同的方式來獲得相同的價值。其中一個(pthread_self()由線程庫(pthreads)提供,另一個(gettid()是一個OS特定的函數)。不同的OS可能提供不同的接口/系統調用來獲得類似於gettid()的線程ID,因此您不能依靠gettid()在便攜式應用。

+1

作爲次要說明,轉換爲整數也適用於作爲指針類型的'pthread_t',它實際上在許多體系結構中。所以'(long)'可能不太好,但是'(uintptr_t)'現在幾乎可以在所有平臺上運行。 –

+0

謝謝。我以這種方式打印線程ID:'pthread_t tId = pthread_self(); qDebug()<<「\ nConsumer:」<< tId;'並得到「140482062563072」。這個龐大的數字可以有效嗎,或者我錯過了一些觀點? –

+1

@TheIndependentAquarius'pthread_t'是一個不透明的類型。它可以是'long long'或'struct'指針或實現選擇的任何其他類型。你看到的可能是一個id或一個地址。你不能依靠它。 'gcc -E -P file.cpp | grep pthread_t'可以用來查找你的'typedef''的實現。但是在其他系統上可能會有所不同。如果你需要使用'pthread_t'來存儲它,比較使用'pthread_equal()'。正如Jens所說,你可以將它轉換爲'uintptr_t'來打印,以便它可以用於指針類型和整數類型。 –

4

pthread_self() returns the process-wide unique pthread-id.

gettid()返回(具體執行並行線程)系統範圍內唯一的線程ID(在Linux上)。

the TID(thread id) returned by gettid() is unique inside a process 

是。

(or inside a program with multiple processes, 

是的。

inside a process, different thread has different thread id. 

是的。

the TID returned by pthread_self() is unique across processes, 

different thread has different TID on the same machine at the same time. 

是在同一過程中,沒有在整個機器。由於gettid()是Linux專用的,因此不具有可移植性,系統廣泛標識pthread的唯一方式是使用它的(系統範圍唯一)父進程標識,由getpid()及其(進程範圍唯一)由pthread_self()返回的pthread-id。

2

這是區別概念術語和實際軟件實體(屬於特定的軟件抽象)之間的一個有趣的研究。

首先,注意類型這兩個調用。

pid_t gettid(void); 
pthread_t pthread_self(void); 

一個是pid_t另一個是pthread_t。這兩個都是指稱爲thread的共同概念實體,但不同的類型意味着這兩個不同的software entities。它們是thread id的不同表示,並且在合併它的軟件抽象中是有意義的。因此,pthread_t合理只有在由pthread包支持的抽象中,而pid_t在合併此類型的抽象(即在pid_t中處理的Linux系統調用)內有意義。

您應該根據上下文使用正確的類型。在需要pid_t的上下文中,需要使用pthread_tpid_t的上下文中使用pthread_t - 無論它們是否可能引用同一個線程。

這些上下文中的每一個都有規定的比較和相等的語法。 pid_t可以由==運營商直接比較,而pthread_t必須通過調用pthread_equal進行比較。

此雙重表示/軟件抽象的原因是pthread庫是一個可在不同操作系統上實現的可移植線程庫。 pthread庫的不同實現保證thread id類型將始終爲pthread_t。這些線程可能映射到操作系統特定的thread entity,其OS標識符取決於操作系統(例如,對於Linux,它是pid_t;對於Windows,它是DWORD)。因此,雖然底層實現可能因操作系統不同而不同,但是針對pthread抽象的代碼仍然可以跨操作系統使用(只要您將自己侷限於pthread抽象)即可。