1

2つのオーバーロードされた関数を持つクラス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 に答える