C++ C+中的临界截面和返回值+;
在尝试从头创建线程安全的容器类时,我遇到了从访问方法返回值的问题。例如,在Windows中: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; } 现在我假设这种类型的方法根本不是线程
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 §ion;
public:
CriticalLock(CriticalSection &cs) : section(cs)
{
EnterCriticalSection(section);
}
~CriticalLock()
{
LeaveCriticalSection(section);
}
};
用法:
myNode getSomeData( )
{
CriticalLock lock(myCritSec); // automatically released.
...
}
但是retobj存储在堆栈上?除非声明为“静态”,否则覆盖复制的数据应该不会有问题。除非发生异常情况,
retobj
应该在堆栈上,并且每个线程都应该有自己的堆栈。当您使用预先分配的内存时,这种竞争条件更常见,并且必须锁定访问以防止共享。@事实上,好的,好的,只要返回值存储在堆栈上,我就可以了。