многопоточность — откуда компилятор узнает, что нельзя оптимизировать операторы изнутри блокировки / разблокировки? использование boost :: spinlocks в переполнении стека

Класс с двумя перегруженными 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);
}
}

1

Решение

Операции блокировки в конечном итоге будут использовать встроенные функции компилятора, которые выполняют некоторый тип атомарных операций. Компилятор знает, что эти операции не должны быть перезаписаны, и не будет оптимизировать «прошлое». Все хорошо.

3

Другие решения

Других решений пока нет …