在尝试从头开始创建一个线程安全的容器类时,我遇到了从访问方法返回值的问题。例如在Windows中:
myNode getSomeData( )
{
EnterCriticalSection(& myCritSec);
myNode retobj;
// fill retobj with data from structure
LeaveCriticalSection(& myCritSec);
return retobj;
}
现在我认为这种类型的方法根本不是线程安全的,因为在代码释放临界区之后,另一个线程能够出现并在第一个线程返回之前立即覆盖retobj
。那么,以线程安全的方式将retobj
返回给调用者的优雅方法是什么?
答案 0 :(得分:8)
不,它是线程安全的,因为每个线程都有自己的堆栈,那就是retobj
。
然而,它肯定不是例外安全的。在RAII风格的对象中包装关键部分会有所帮助。有点像...
class CriticalLock : boost::noncopyable {
CriticalSection §ion;
public:
CriticalLock(CriticalSection &cs) : section(cs)
{
EnterCriticalSection(section);
}
~CriticalLock()
{
LeaveCriticalSection(section);
}
};
用法:
myNode getSomeData( )
{
CriticalLock lock(myCritSec); // automatically released.
...
}
答案 1 :(得分:2)
这是C ++,retobj
具有自动存储类型,因此它存储在堆栈中。
每个线程都有自己的堆栈,因此另一个线程在返回之前不能破坏retobj
的值。