我的应用程序用来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>
在多个线程上使用并且仅被一个线程修改的a怎么样?当然,EnterCriticalSection
无论何时更改,我都必须锁定它,但read
访问权限又如何呢?当我从中读取内容(例如if (a_map["foo"] == 0)
)时是否可以通过单个线程进行更改,是否应该将其锁定?例如这样?
EnterCriticalSection(&cs);
bool val = a_map["foo"];
LeaveCriticalSection(&cs);
if (val == 0) {
...
}
由于仅在一个线程中更新变量,而在其他线程中读取变量,并且由于变量的类型是atomic,因此不需要任何锁定机制。您需要做的就是声明它volatile
,您已经完成了。如果变量是非原子类型的(例如,map
在32位体系结构上为,甚至只是64位整数),则需要锁定。
C&C ++标准甚至在简单的机器语言操作(例如读取an)上也不假定操作的原子性int
,但是如果您使用的winapi
是on x86
,则可以保证操作的原子性。(因此,如果您想编写可移植的代码,即使您int
在一个线程上编写一个并且仅从其他线程读取它,也请使用锁定。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句