C++ C+中的临界截面和返回值+;

C++ C+中的临界截面和返回值+;,c++,multithreading,winapi,return-value,critical-section,C++,Multithreading,Winapi,Return Value,Critical Section,在尝试从头创建线程安全的容器类时,我遇到了从访问方法返回值的问题。例如,在Windows中: myNode getSomeData( ) { EnterCriticalSection(& myCritSec); myNode retobj; // fill retobj with data from structure LeaveCriticalSection(& myCritSec); return retobj; } 现在我假设这种类型的方法根本不是线程

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

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

现在我假设这种类型的方法根本不是线程安全的,因为在代码释放关键部分之后,另一个线程能够出现,并在第一个线程返回之前立即覆盖
retobj
。那么,如何将代码< > ReButj>代码>以线程安全的方式返回给调用方?< > P>这是C++,而<>代码> ReButj具有自动存储类型,因此它被存储在堆栈上。
每个线程都有自己的堆栈,因此在返回
retobj
之前,另一个线程无法删除该值。

否,它是线程安全的,因为每个线程都有自己的堆栈,这就是
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.
  ...
} 

但是retobj存储在堆栈上?除非声明为“静态”,否则覆盖复制的数据应该不会有问题。除非发生异常情况,
retobj
应该在堆栈上,并且每个线程都应该有自己的堆栈。当您使用预先分配的内存时,这种竞争条件更常见,并且必须锁定访问以防止共享。@事实上,好的,好的,只要返回值存储在堆栈上,我就可以了。