запись-запись данных из std :: set insert () и find ()?

Чтобы поэкспериментировать с потоком-дезинфицирующим средством, я создал крошечную программу на C ++, которая по своему назначению содержит гонку данных. Действительно, Цан обнаруживает ошибку, отлично! Однако я озадачен сгенерированным сообщением …

  1. Сообщает написать-записать гонка данных, где я бы ожидал читай пиши гонка. Я бы надеялся, что find() не пишет в моем контейнере. Если я сделаю еще одну небольшую корректировку кода, пытаясь получить const версия set::find(), та же самая гонка записи-записи, кажется, остается.
  2. Это показывает конфликт записи между 4 байтами атомное запись и 8-байтовая запись по одному адресу. Кажется странным, что к одному и тому же полю в классе контейнера обращаются два таких разных типа доступа.

Есть ли возможность использовать const find() что не пишет в контейнер STL?

Это протестированная программа C ++:

/*****************************************************************************
* Small example with an inter-thread data race that is not obvious.
* the error is a consequence of the non-threadsafeness of the STL containers.
* Threading is created through portable C++11 constructs.
* Tsan does detect the data race(?).
*
* Compile with one of:
* g++-4.8 -std=c++11 -g -Wall -o race-stl11b race-stl11b.cc -pthread
* g++-4.8 -std=c++11 -g -Wall -fsanitize=thread -fPIE -o race-stl11b-tsan race-stl11b.cc -ltsan -pie -pthread
******************************************************************************/

#include <iostream>
#include <thread>
#include <set>

int main()
{
// create an empty bucket
std::set<int> bucket;

// Use a background task to insert value '5' in the bucket
std::thread t([&](){ bucket.insert(5); });

// Check if value '3' is in the bucket (not expected :-)
bool contains3 = bucket.find(3) != bucket.cend();
std::cout << "Foreground find done: " << contains3 << std::endl;

// Wait for the background thread to finish
t.join();

// verify that value '5' did arrive in the bucket
bool contains5 = bucket.find(5) != bucket.cend();
std::cout << "Background insert: " << contains5 << std::endl;

return 0;
}

И это (часть) вывода цана:

WARNING: ThreadSanitizer: data race (pid=21774)

Write of size 8 at 0x7d080000bfc8 by thread T1:
#0 <null> <null>:0 (libtsan.so.0+0x00000001e2c0)
#1 deallocate /usr/include/c++/4.8/ext/new_allocator.h:110 (exe+0x000000002a79)
#2 deallocate /usr/include/c++/4.8/bits/alloc_traits.h:377 (exe+0x000000002962)
#3 _M_destroy /usr/include/c++/4.8/bits/shared_ptr_base.h:417 (exe+0x00000000306b)
#4 <null> <null>:0 (libstdc++.so.6+0x0000000b5f8a)

Previous atomic write of size 4 at 0x7d080000bfc8 by main thread:
#0 <null> <null>:0 (libtsan.so.0+0x00000000da45)
#1 __exchange_and_add /usr/include/c++/4.8/ext/atomicity.h:49 (exe+0x000000001c9f)
#2 __exchange_and_add_dispatch /usr/include/c++/4.8/ext/atomicity.h:82 (exe+0x000000001d56)
#3 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/4.8/bits/shared_ptr_base.h:141 (exe+0x00000000390d)
#4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/4.8/bits/shared_ptr_base.h:553 (exe+0x00000000363c)
#5 std::__shared_ptr<std::thread::_Impl_base, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/4.8/bits/shared_ptr_base.h:810
(exe+0x00000000351b)
#6 std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() /usr/include/c++/4.8/bits/shared_ptr.h:93 (exe+0x000000003547)
#7 thread<main()::__lambda0> /usr/include/c++/4.8/thread:135 (exe+0x0000000020c3)
#8 main /home/......./race-stl11b.cc:22 (exe+0x000000001e38)

Спасибо за любые отзывы,
Jos

4

Решение

Похоже, ThreadSanitizer дает ложный положительный результат в реализации std :: thread.

Сокращение вашего примера, чтобы он не выполнял никаких манипуляций с наборами, например:

#include <iostream>
#include <thread>
#include <set>

int main()
{
std::set<int> bucket;
std::thread t([&](){ /*bucket.insert(5);*/ });
t.join();

return 0;
}

По-прежнему выдает ту же ошибку в ThreadSanitizer.

Обратите внимание, что ThreadSanitizer делает НЕ найти ваше состояние гонки чтения-записи.

1

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

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

По вопросам рекламы [email protected]