1

从单独的线程调用具有两个重载operator()函数的类。请参阅下面代码中的//注释。

优化器是否知道不要entryadd = mSpread * ENTRY_MULTIPLIER超过lock()?

struct Algo1
{   
    boost::detail::spinlock mSpreadLock;

    Algo1() : mSpreadLock() {}

    //called from thread 1 
    inline void operator()(const indata &signal) 
    {
        if ( signal.action() == SEND )
        {
            double entryadd;
            mSpreadLock.lock();
            entryadd = mSpread * ENTRY_MULTIPLIER; //isnt it possible for compiler to optimize this before the lock? 
            mSpreadLock.unlock();
            FunctionCall(entryadd);
        }
    }

    //called from thread2
    inline void operator()(const indata2 &bospread) 
    {
        boost::detail::spinlock::scoped_lock mylock(mSpreadLock);
        mSpread = bospread.spread();
    }
}

那这个呢?

{
    mSpreadLock.lock();
    double entryadd = mSpread * ENTRY_MULTIPLIER; 
    mSpreadLock.unlock();
{

我的定义会entryadd移到函数的顶部吗?

除非我错过了一些东西.. 似乎代码块中的锁定和解锁将不起作用。必须使用 scoped_lock。 boost::detail::spinlock::scoped_lock mylock(mSpreadLock),它将在函数调用期间锁定。

当然我可以像这样破解它:(但效率较低)

inline void operator()(const indata &signal) 
{
    if ( signal.action() == SEND )
    {
        double entryadd;
        {
            boost::detail::spinlock::scoped_lock mylock(mSpreadLock);
            entryadd = mSpread * ENTRY_MULTIPLIER; 
        }
        FunctionCall(entryadd);
    }
}
4

1 回答 1

3

锁定操作最终将使用执行某种原子操作的编译器内置函数。编译器知道这些操作不能被重新编码并且不会优化“过去”它们。一切都好。

于 2012-12-18T19:46:18.637 回答