7

在尝试从头开始创建线程安全的容器类时,我遇到了从访问方法返回值的问题。例如在 Windows 中:

myNode getSomeData( )
{
  EnterCriticalSection(& myCritSec);
  myNode retobj;
  // fill retobj with data from structure
  LeaveCriticalSection(& myCritSec);
  return retobj;
}

现在我认为这种类型的方法根本不是线程安全的,因为在代码释放临界区之后,另一个线程能够出现并retobj在第一个线程返回之前立即覆盖。那么retobj以线程安全的方式返回调用者的优雅方式是什么?

4

2 回答 2

8

不,它是线程安全的,因为每个线程都有自己的堆栈,这就是堆栈retobj

但是,它肯定不是异常安全的。将关键部分包装在 RAII 样式的对象中会有所帮助。就像是...

class CriticalLock : boost::noncopyable {
  CriticalSection &section;

public:
  CriticalLock(CriticalSection &cs) : section(cs)
  {
    EnterCriticalSection(section);
  }

  ~CriticalLock()
  {
    LeaveCriticalSection(section);
  }
};

用法:

myNode getSomeData( )
{
  CriticalLock  lock(myCritSec);  // automatically released.
  ...
} 
于 2012-07-25T15:24:57.350 回答
2

这是C++,并且retobj具有自动存储类型,所以它存储在堆栈上。

retobj每个线程都有自己的堆栈,因此另一个线程在返回它之前不能破坏它的值。

于 2012-07-25T15:24:33.883 回答