【发布时间】:2012-03-21 20:45:36
【问题描述】:
假设我有一个程序初始化一个供线程使用的全局变量,如下所示:
int ThreadParameter;
// this function runs from the main thread
void SomeFunction() {
ThreadParameter = 5;
StartThread(); // some function to start a thread
// at this point, ThreadParameter is NEVER modified.
}
// this function is run in a background worker thread created by StartThread();
void WorkerThread() {
PrintValue(ThreadParameter); // we expect this to print "5"
}
这些问题应该适用于人们可能遇到的任何通用处理器架构。我希望解决方案是可移植的——而不是特定于具有更强内存保证的架构,例如 x86。
- 一般性问题:尽管很常见,但这在所有处理器架构中真的安全吗?如果没有,如何确保安全?
- 全局变量不是
volatile;在StartThread()通话后是否可能会重新排序并让我感到厌烦?如何解决这个问题? - 假设计算机有两个处理器,它们都有自己的缓存。主线程在第一个处理器上运行,工作线程在第二个处理器上运行。假设在程序开始运行
SomeFunction()之前,包含ThreadParameter的内存块已经被分页到每个处理器的缓存中。SomeFunction()将5写入ThreadParameter,它被存储在第一个处理器的缓存中,然后启动在第二个处理器上运行的工作线程。第二个处理器上的WorkerThread()会不会看到ThreadParameter的未初始化数据而不是5的预期值,因为第二个处理器中的内存页面还没有看到来自第一个处理器的更新? - 如果需要不同的东西 - 考虑到我可以使用指向更复杂的数据类型的指针而不是简单的
int,如何最好地处理这个问题,而这些数据类型不一定在多线程环境中使用?李>
如果我的担心没有根据,我不需要担心的具体原因是什么?
【问题讨论】:
-
SomeFunction 将调用多个 WorkerThreads,我假设。我认为您的问题更像是:“同时阅读会给我带来问题吗?” .... ?
-
好吧,当使用 POSIX 线程时,您可以使用
pthread_once()解决全局变量初始化难题——我不确定这如何转化为您对“便携”的定义。 -
我想最好的解决方案是
boost:shared_mutex并将只读复制到每个线程中。 -
当你需要从 ThreadParameter 中读取时使用锁呢?
-
我很抱歉,但我需要逐步理解这一点。我一直相信
volatile的存在是为了让程序员可以告诉C(它是C,对吗?)编译器它应该假设其他东西会触及地址。您是否有不想使用volatile的原因?
标签: c++ c multithreading thread-safety