转自:
http://boost.ez2learn.com/doc/html/thread/thread_local_storage.html
http://www.oschina.net/code/snippet_54334_872
概述
線程本地化存儲允許多個線程對像擁有特定數據的獨立拷貝. 單線程程序通常使用的的靜態數據和全局數據在多線程程序中會引發訪問競爭,死鎖,或者數據破壞 . 一個例子就是 C運行庫中的 errno
變量, 該變量放C標準庫中函數的錯誤代碼. 對於支持多線程的編譯器來說,為每個線程提供一個獨立的errno
是常見的做法,以此避免多個線程競爭對它的訪問和更新(這也是POSIX 標準要求的).
儘管編譯器通常提供一些形式的語法擴展來方便標記線程本地存儲(比如用於 static
或名字空間內變量聲明前的 __declspec(thread)
或__thread
標記), 但是這些支持是不可移植的, 也僅限於某些用途, 比如只支持 POD 類型.
由boost::thread_specific_ptr
實現的可移植的線程本地化存儲
boost::thread_specific_ptr
提供了一個線程本地化存儲機制的可移植實現,每個boost::thread_specific_ptr
指向一個對像,這些對像要求在不同的線程間有不同的值. 當前線程對應的對象的值可以通過成員函數 get()
或是通過 *
and ->
操作deference operators. 這些對象的初始值為 NULL,
需要通過函數 reset()
改變當前線程對應的值.
如果通過reset()
將boost::thread_specific_ptr
的指向改變, 那麼在此之前的值會被清理, 另外, 存儲的值可以通過成員函數release()
置為NULL
, 該函數同時返回這個值, 這樣應用程序可以有機會銷毀這個值關聯的對象.
線程退出時清理
當一個線程退出, boost::thread_specific_ptr
實例 所關聯的對象會被銷毀. 通常銷毀的動作通過對被指向的對象調用delete
完成, 這個行為也可以通過向
boost::thread_specific_ptr
對像構造時傳遞一個清理函數func()
來重載.此時, 所指向對像通過調用 func(p)
來銷毀 .這些清理函數調用順序不是確定的 . 如果一個清理函數將 對像關聯的值設置為一個被清理過的值, 這個值會被添加到清理列表中. 當所有 boost::thread_specific_ptr
對像被置為空時,清理過程結束.
示例代码:
// 一个使用boost::thread_specific_ptr线程本地存储的示例,value将不受其它线程影响.
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
#include <cassert>
boost::thread_specific_ptr<int> value;
void increment()
{
int* p = value.get();
++*p;
}
void thread_proc()
{
value.reset(new int(0)); // initialize the thread's storage
for (int i=0; i<10; ++i)
{
increment();
int* p = value.get();
assert(*p == i+1);
}
}
int main(int argc, char* argv[])
{
boost::thread_group threads;
for (int i=0; i<5; ++i)
threads.create_thread(&thread_proc);
threads.join_all();
}