简体   繁体   中英

Win32 threading

My application uses CreateThread to create a secondary (and only) thread that executes every 10ms , like the following pseudocode :

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;
}

The variables are declared as following:

static volatile bool manual_action_execute_thread_run;
static volatile bool automatic_action_execute_inprogress;

The first one takes the value of true before even start my thread so i don't use locking on this. The second takes a false at first.

I am using ::automatic_action_execute_inprogress to control some behaviour on second thread which only changes on the main thread .

QUESTION(s):

1) Since i only update ::automatic_action_execute_inprogress on main thread and just reading it on second thread i still need to lock it first using EnterCriticalSection ? Or the locking is only restricted to the shared variables that are changed on both threads?

2) What about a <map> that's used on multiple threads and modified by just one? Certainly i have to lock it with EnterCriticalSection whenever changes but what about read access? Should i lock it when i read from it (like if (a_map["foo"] == 0) ) if can change even by a single thread? Like this for example?

EnterCriticalSection(&cs);
   bool val = a_map["foo"];
LeaveCriticalSection(&cs);

   if (val == 0) {
      ...
   }

Since you only update your variable in one thread and just read it in other threads, and since the type of the variable is atomic , you do not need any locking mechanism. All you need to do is declare it volatile , which you have already done. If the variable was of a non-atomic type, (say, a map , or even just a 64-bit integer on a 32-bit architecture,) then you would need locking.

The C & C++ standard does not presume atomicity of operations even on simple machine-word operations like reading an int , but if you are using winapi then you are on x86 , which guarantees it. (So, if you want to write portable code, use locking even if you are writing an int on one thread and only reading it from other threads.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM