Всем привет. Локализовал код, на который жалуется санитайзер. Не вижу здесь своей ошибки, а вы?
#include <thread>
#include <atomic>
#include <mutex>
#include <vector>
#include <chrono>
using namespace std;
class Test {
mutex m_mtx;
atomic_flag m_spin_lock;
vector<int> m_data;
public:
void add() {
while (m_spin_lock.test_and_set(memory_order_relaxed))
this_thread::yield();
atomic_thread_fence(memory_order_acquire);
while (true) {
this_thread::sleep_for(300ms);
std::scoped_lock lck{m_mtx};
m_data.push_back(4);
}
m_spin_lock.clear(memory_order_release);
}
void read() {
size_t sz;
while (true) {
if (! m_spin_lock.test_and_set(std::memory_order_acquire)) {
sz = m_data.size();
m_spin_lock.clear(std::memory_order_release);
}
else {
std::scoped_lock lck{m_mtx};
sz = m_data.size();
}
this_thread::sleep_for(1s);
}
}
}test;
int main() {
jthread rt(&Test::read, &test);
this_thread::sleep_for(10ms);
test.add();
}
$ g++ 1.cc -std=c++20 -fsanitize=thread
$ ./a.out
WARNING: ThreadSanitizer: data race (pid=63269)
Write of size 8 at 0x56247be53a80 by main thread (mutexes: write M11):
#0 void std::vector<int, std::allocator<int> >::_M_realloc_insert<int>(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, int&&) <null> (a.out+0xd9a47)
#1 int& std::vector<int, std::allocator<int> >::emplace_back<int>(int&&) <null> (a.out+0xd970c)
#2 std::vector<int, std::allocator<int> >::push_back(int&&) <null> (a.out+0xd9595)
#3 Test::add() <null> (a.out+0xd819b)
...
Previous read of size 8 at 0x56247be53a80 by thread T1:
#0 std::vector<int, std::allocator<int> >::size() const <null> (a.out+0xd899d)
#1 Test::read() <null> (a.out+0xd7bc2)
...
Со шлангом аналогично.