Возможно ли, что компилятор может изменить порядок операций до и после блокировки, когда блокировка выполняется в новой области?
Например:
std::cout << "started from ...
std::cout << "exited from ...
locking
or:
locking
std::cout << "started from ...
std::cout << "exited from ...
Полный пример кода:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int counter = 0;
bool updated = false;
void foo()
{
std::cout << "started from : " << std::this_thread::get_id() << std::endl;
//or any other operation before locking
{
//explicit scope
std::scoped_lock lk{mtx};
if(counter++)
updated = true;
std::cout << "ctr: " << counter << std::endl;
std::cout << "upd: " << updated << std::endl;
std::cout << "performed from : " << std::this_thread::get_id() << std::endl;
}
std::cout << "exited from : " << std::this_thread::get_id() << std::endl;
//or any other operation after releasing lock
}
int main()
{
std::thread t1(foo);
std::thread t2(foo);
t1.join();
t2.join();
}
выход был до сих пор стабильным:
started from : 140096075392768
ctr: 1
upd: 0
performed from : 140096075392768
exited from : 140096075392768
started from : 140096083785472
ctr: 2
upd: 1
performed from : 140096083785472
exited from : 140096083785472
но есть ли гарантия, что он останется стабильным?
Можно ли получить следующий вывод:
started from : 140096075392768
exited from : 140096075392768
ctr: 1
upd: 0
performed from : 140096075392768
ctr: 2
upd: 1
performed from : 140096083785472
started from : 140096083785472
exited from : 140096083785472
Так что в обоих потоках операции под блокировкой переупорядочены с несинхронизированными операциями.