C ++中的关键部分和返回值

时间:2012-07-25 15:20:11

标签: c++ multithreading winapi return-value critical-section

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

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

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

2 个答案:

答案 0 :(得分: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.
  ...
} 

答案 1 :(得分:2)

这是C ++,retobj具有自动存储类型,因此它存储在堆栈中。

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