我使用boost's lock-free queue版本1.68创建了无锁对象池。尽管它似乎工作正常,但我仍在函数pop()
中从clang的线程清除程序中收到这些警告。
WARNING: ThreadSanitizer: data race (pid=32452)
Write of size 2 at 0x7b4400081e00 by thread T54 (mutexes: write M3349, write M3517):
#0 boost::lockfree::detail::tagged_index::set_index(unsigned short) /opt/boost/boost/lockfree/detail/freelist.hpp:292:15 (Exchange-tests+0xb37c09)
#1 boost::lockfree::detail::fixed_size_freelist<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, boost::lockfree::detail::runtime_sized_freelist_storage<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, std::allocator<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node> > >::deallocate_impl(unsigned short) /opt/boost/boost/lockfree/detail/freelist.hpp:592:33 (Exchange-tests+0xb3c31f)
#2 void boost::lockfree::detail::fixed_size_freelist<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, boost::lockfree::detail::runtime_sized_freelist_storage<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, std::allocator<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node> > >::deallocate<true>(unsigned short) /opt/boost/boost/lockfree/detail/freelist.hpp:580:13 (Exchange-tests+0xb3c23b)
#3 void boost::lockfree::detail::fixed_size_freelist<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, boost::lockfree::detail::runtime_sized_freelist_storage<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node, std::allocator<boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::node> > >::destruct<true>(boost::lockfree::detail::tagged_index) /opt/boost/boost/lockfree/detail/freelist.hpp:478:9 (Exchange-tests+0xb3c1d7)
#4 bool boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::pop<unsigned long>(unsigned long&) /opt/boost/boost/lockfree/queue.hpp:418:39 (Exchange-tests+0xb3c102)
#5 boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::pop(unsigned long&) /opt/boost/boost/lockfree/queue.hpp:375:16 (Exchange-tests+0xb3bda8)
#6 ObjectPool<MarketsController>::borrowObj()
...
Previous atomic read of size 4 at 0x7b4400081e00 by thread T52 (mutexes: write M3339, write M3518):
#0 __tsan_atomic32_load /tmp/final/llvm.src/projects/compiler-rt/lib/tsan/rtl/tsan_interface_atomic.cc:535:3 (Exchange-tests+0x503e11)
#1 std::atomic<boost::lockfree::detail::tagged_index>::load(std::memory_order) const /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/atomic:250:2 (Exchange-tests+0xb37e97)
#2 bool boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::pop<unsigned long>(unsigned long&) /opt/boost/boost/lockfree/queue.hpp:394:54 (Exchange-tests+0xb3beca)
#3 boost::lockfree::queue<unsigned long, boost::lockfree::fixed_sized<true> >::pop(unsigned long&) /opt/boost/boost/lockfree/queue.hpp:375:16 (Exchange-tests+0xb3bda8)
#4 ObjectPool<MController>::borrowObj()
...
在boost的代码之后,我看到了这个boost/lockfree/detail/freelist.hpp:292
:
void set_index(index_t i)
{
index = i; // this line
}
和这个boost/lockfree/queue.hpp:394:54
:
tagged_node_handle next = head_ptr->next.load(memory_order_acquire);
我不确定该如何反应,但是我应该如何担心?这是加强剂还是消毒剂中的错误?还是我做错了什么?