有一個修飾字可以讓一個變數安全的讓每個 Thread 都取用同樣的資料即 volatile
但我們如果想要反過來讓每個 Thread 不會影響各自的資料呢?就得用到 TLS 嘍…
MSDN 官方的文件說明在 Visual Studio 中怎麼宣告 TLS 變數:Thread Local Storage
當然要達到 TLS 的方法其實非常多…流程上可行的話…使用 mutex 是更簡單易維護的方式…
再者讓 Thread 的主體中複製一份該變數的內容也可以…但若會使用到的資料多起來會相當累人…
或者就是簡單在全域的變數宣告前面加上 __declspec(thread) 即可達到 TLS 的效果…
以下使用簡單的範例說明使用了 __declspec(thread) 的效果…
__declspec(thread) int g_nTLS = 0;
UINT SampleThread(LPVOID pParam)
{
int *nThread = (int*)pParam;
do
{
cout << "Thread Number : " << *nThread << " : " << g_nTLS++;
} while (g_nTLS < 1000000);
return TRUE;
}
void StartTwoThread()
{
int x = 1, y = 2;
AfxBeginThread(SampleThread, (LPVOID)&x, THREAD_PRIORITY_NORMAL);
AfxBeginThread(SampleThread, (LPVOID)&y, THREAD_PRIORITY_NORMAL);
}
若全域變數 g_nTLS 沒有宣告為 TLS 變數…
輸出的結果應該會看到不規則的有時 g_nTLS 被第 1 個啟動的 Thread 加了有時被第 2 個…
加了 __declspec(thread) 後…雖然印出來的順序不一定整齊…
但至少 Thread 1、2 都會乖乖的印出自己的 0-999999
如果覺得 __ 開頭的這種修飾字很難看…也可以像 MSDN 文件裡一樣
#define Thread __declspec( thread )
再改用 Thread int tls_i; 宣告也行…
此外宣告 TLS 變數的對像也有些限制,MSDN 中都有範例…
沒有留言:
張貼留言