0

我对本质上是 pthread 的包装器的第三方库有疑问。
它的join函数是这样实现的:

            bool Join() throw ()
            {
                ThreadState s;
                {
                    CCriticalSectionLock L(m_CS);
                    s = m_CurrentThreadState;
                }

                if (s == Started) {...}
            }

不应该将if (s == Started) {...}代码放在定义锁的块中吗?

实际上,关键部分仅包括变量赋值,作为基本操作不需要它。

谢谢你。

4

4 回答 4

2

关键部分的重点是保护m_CurrentThreadState字段的读取,这可能会被其他线程更改。

于 2012-12-03T15:48:24.927 回答
2

不应该将if (s == Started) {...}代码放在定义锁的块中吗?

简短的回答:没有。

更长的答案:不,因为关键部分仅涵盖m_CurrentThreadState.

在这段代码s中是一个局部堆栈变量,每个线程都有它自己的副本(即它不需要被保护)。

代码阻止访问m_CurrentThreadState并读取它的值(进入s)。然后,它使用 s 中的值(这将是一致的,即使另一个线程修改了m_CurrentThreadState)。

于 2012-12-03T15:49:12.297 回答
1

临界区确保读取共享变量 ( m_CurrentThreadState) 以原子方式完成。C++ 不保证基本操作是原子的,尽管现在人们可以使用std::atomic而不是锁。

是否需要为访问之后的任何逻辑维护锁定是一个需要仔细分析线程如何交互的问题。希望库作者进行了分析,并确定在不维护锁的情况下对值进行操作是安全的。

于 2012-12-03T15:50:46.397 回答
1

该变量sm_CurrentThreadState

看起来该函数希望在短时间内保持锁定,因此检查此状态值的副本。

这段时间状态值是否发生变化都没有关系,代码无论如何都会执行。

于 2012-12-03T15:50:47.793 回答