Приветствую. Мьютексы не обеспечевуют sequentially-consistent порядок, т.е. если существуют два мьютекса, которые контролируют доступ каждый к своим данным, в некотором потоке сначала берем первый мьютекс, модифицируем, берем второй мьютекс, модифицируем. Для данного потока порядок четкий - сначала 1 затем 2, для остальных же потоков вполне может быть сначала 2 затем 1.
Вопрос, как сделать sequentially-consistent порядок для всех потоков? Идею выражу в коде:
#include <thread>
#include <mutex>
#include <cassert>
using namespace std;
#define WITH_FENCE 0
int a_data, b_data;
mutex a_mtx, b_mtx;
atomic_int cnt = 0;
void write_a() {
lock_guard lck(a_mtx);
a_data = 5;
#if WITH_FENCE
atomic_thread_fence(std::memory_order_seq_cst);
#endif
}
void write_b() {
lock_guard lck(b_mtx);
b_data = 5;
#if WITH_FENCE
atomic_thread_fence(std::memory_order_seq_cst);
#endif
}
void check() {
while (true) {
lock_guard lck(a_mtx);
#if WITH_FENCE
atomic_thread_fence(std::memory_order_seq_cst);
#endif
if (a_data) {
lock_guard lck_1(b_mtx);
#if WITH_FENCE
atomic_thread_fence(std::memory_order_seq_cst);
#endif
cnt.fetch_add(1, memory_order_relaxed);
return;
}
}
}
int main() {
jthread t0(check);
jthread t1(check);
jthread t0(write_a);
jthread t1(write_b);
assert (cnt == 0 || cnt == 2);
}
Если WITH_FENCE == 0, то порядка не будет точно. Поможет ли WITH_FENCE = 1? Если поможет, то что будет, если будут и другие потоки, которые будут брать данные мьютексы без барьера, будет ли сохранен порядок пусть и с какими-то вмешательствами из других потоков в рандомных местах (вне единого порядка, значит каждый поток видит их по-разному), но все же можно будет сказать в отношении упорядоченных событий (которые с барьером), что условное событие 2 не происходит раньше 1? В общем велком, если написал спутанно последнюю идею, дайте знать, приведу пример.
UPD: для main нет четкого порядка, код поправил
c++, multithreading