[英]Win32 threading
我的應用程序使用CreateThread
創建一個每10ms
執行一次的輔助(也是唯一)線程,如下面的偽代碼:
map<string, int32_t> a_map;
DWORD WINAPI Table::manual_action_execute_thread(LPVOID lpParameter) {
while(Table::manual_action_execute_thread_run) {
...
if (!Table::automatic_action_execute_inprogress) {
...
}
...
if (a_map["blah"] == 0) {
...
}
...
Sleep(10);
}
return 0;
}
變量聲明如下:
static volatile bool manual_action_execute_thread_run;
static volatile bool automatic_action_execute_inprogress;
第一個甚至在啟動我的線程之前就采用true
的值,所以我不使用鎖定。 第二個首先取false
。
我正在使用::automatic_action_execute_inprogress
來控制僅在主線程上更改的第二個線程上的某些行為。
問題):
1)由於我只在主線程上更新::automatic_action_execute_inprogress
而只是在第二個線程上讀取它,我仍然需要先使用EnterCriticalSection
鎖定它? 或者鎖定僅限於在兩個線程上更改的共享變量?
2)在多個線程上使用並僅由一個修改的<map>
怎么樣? 當然,每當更改時我都必須使用EnterCriticalSection
鎖定它,但是read
訪問呢? 我應該在讀取它時鎖定它(比如if (a_map["foo"] == 0)
)如果可以通過單個線程改變? 比如這個?
EnterCriticalSection(&cs);
bool val = a_map["foo"];
LeaveCriticalSection(&cs);
if (val == 0) {
...
}
由於您只在一個線程中更新您的變量並在其他線程中讀取它,並且由於變量的類型是atomic ,因此您不需要任何鎖定機制。 您需要做的就是將它聲明為volatile
,您已經完成了。 如果變量是非原子類型(例如, map
,或者甚至只是 32 位體系結構上的 64 位整數),那么您將需要鎖定。
即使在讀取int
等簡單的機器字操作上,C 和 C++ 標准也不假定操作的原子性,但如果您使用的是winapi
那么您使用的是x86
,這保證了它。 (因此,如果您想編寫可移植代碼,即使您在一個線程上編寫int
並且僅從其他線程讀取它,也要使用鎖定。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.