这个程序在C++;11? 我知道老C++对线程一无所知,所以这是一个关于IL编译器的Q,不是标准的。

这个程序在C++;11? 我知道老C++对线程一无所知,所以这是一个关于IL编译器的Q,不是标准的。,c++,race-condition,c++98,C++,Race Condition,C++98,我最近正在编写一个代码,其中包含如下内容: // runs until sun shines or until shutdown is signaled from another thread // const is here just to make it clear run is not touching variable void run(const bool& shutdown_in_progress) { while(! shutdown_in_progress) //

我最近正在编写一个代码,其中包含如下内容:

// runs until sun shines or until shutdown is signaled from another thread  
// const is here just to make it clear run is not touching variable 
void run(const bool& shutdown_in_progress) 
{
while(! shutdown_in_progress) //1
{
    //populate data
    for (int i = 0; i< data.size();++i)
    {
         if (shutdown_in_progress) //2
             break; // shutdown latency optimization
         do_slow_stuff_with(data[i]);
    }

}
//运行到阳光普照或另一个线程发出关闭信号为止
//const在这里只是为了说明run并没有接触变量
无效运行(持续停止和关闭正在进行)
{
当(!正在关闭)//1
{
//填充数据
对于(int i=0;i
现在让我们假设我添加了同步,以访问正在进行的shutdown_(因此该变量上没有争用条件)

我是否错误地认为,即使使用pthread\u mutex\u lock/unlock保护对bool的访问,编译器也可以进行破坏性的优化,将while(//1)替换为if,并完全删除//2,因为它知道变量必须为false。 或者编译器有办法在一个变量被同步代码包围时检测它可能发生的变异


<>这不是一个理论问题,我在用一个老的G+编译器编译嵌入式系统:(

< P>),正如你说的,你在这里超出了C++标准的限制。实际上,有编译器假设<代码> StudioWixIn进程< /C>不改变,如果他们在代码中不能证明任何东西,而盖伊

在您的情况下,
shutdown\u In\u progress
是对布尔变量的引用。因此,编译器通常不知道该变量是否使用其他名称访问。例如,它可能引用一个全局变量,该变量可能会被
do\u slow\u stuff\u with
更改。如果该函数的源代码在同一个文件,并且该函数中没有对任何布尔变量的赋值,别名分析可能会启动,并告诉编译器没有对任何布尔变量的写访问,因此肯定没有别名
shutdown\u in\u progress
。但是,一旦调用当前翻译单元之外的函数,旧版本的gcc无法优化访问

gcc可能还有第二种方法来证明无法访问由
shutdown in_progress
引用的布尔变量,即通过跟踪是否有任何其他对创建的真实目标的引用。例如,如果引用的目标是调用方的本地变量,而调用方从未传递在变量到任何其他函数时,gcc可以确保没有别名,因此该变量无法更改不适用,因为您肯定已将
shutdown\u in\u progress
的地址传递给另一个可能启动shutdown的函数,或者它是一个全局变量

<> P>最后,GCC确保不优化对变量声明的访问,即“代码> Value。而C++标准不能保证任何与线程相关的易失性变量,即使在实践中,如果您尝试通过使用不同步的变量来同步,也可能会导致非常意外的结果,而不使用pTrimePrimiTi。在这种情况下,使用volatile变量似乎是安全的。volatile的问题是,它们确保在分配给多个volatile变量时写入指令的顺序正确,但不能保证读卡器按照该顺序观察写入的效果


最后一点,如果您不添加pthread函数调用,并且拥有一个邪恶的处理器体系结构,那么执行您编写的函数的一个处理器内核可能会在不确定的时间内使用引用的布尔变量的过时缓存副本。

好的资源:这无法以其当前形式回答。来自语言人员ctive一切都在C++11之前进行,因为它没有线程意识。但是编译器会提供编译器可能不提供的保证。如果平台是posix,并且您有pthreads,那么库和编译器很可能会一起工作来实现它work@ChrisCooper你是说pthread_mutex*+volatile可以让它工作,但只需使用其中一个会引起疼痛和疼痛sadness@DavidRodríguez dribeas我想我在我的Q中提到了这一点。从ISO的角度来看,这是UB,我关心的是RL编译器,特别是g++和pthread组合。g++编译器有多旧?你可能会研究升级它,这方面的编译器可能有点问题。