簡體   English   中英

Win32線程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM