将 std::atomic_flag 与工作线程一起使用时出现问题

Issue using std::atomic_flag with worker thread

本文关键字:问题 一起 工作 atomic std flag 线程      更新时间:2023-10-16

很抱歉冗长 - 我尽力将我的代码示例压缩为一个功能最小的类和main()方法。

我正在尝试使用atomic_flag来通知工作线程中的_rx()在调用stop()时退出。

我相信问题在于尝试创建我的工作线程,

thread SanityTestThread(&SanityTest::_rx, *this);

这不知何故与我的atomic_flag冲突

代码示例(不编译):

 #include <cstdio>
 #include <chrono>
 #include <unistd.h>
 #include <atomic>
 #include <iostream>
 #include <thread>
 using namespace std;
 class SanityTest
 {
   public:
     SanityTest(){}
     void start();
     void stop();
   private:
     void _rx();
     atomic_flag flag;
 }; // end class SanityTest
void SanityTest::_rx()
{
  while(flag.test_and_set())
  {
    this_thread::sleep_for(chrono::seconds(1));
    cout << "'sup foo" << endl;
  }
} // end _rx
void SanityTest::start()
{
  flag.test_and_set();
  thread SanityTestThread(&SanityTest::_rx, *this);
  SanityTestThread.detach();
} // end start
void SanityTest::stop()
{
  flag.clear();
} // end start
int main(){
  SanityTest s;// = SanityTest();
  s.start();
  this_thread::sleep_for(chrono::seconds(10));
  s.stop();
  return 0;
} // end main

作为记录,我可以通过删除对atomic_flag的所有引用并将我的 _rx() 循环替换为 for 循环来编译和运行,如下所示:

void SanityTest::_rx()
{
  for(int i=0; i <=10; ++ i)
  {
    this_thread::sleep_for(chrono::seconds(1));
    cout << "'sup foo" << endl;
  }
} // end _rx

编译器错误:

In file included from ./SanityTest.cpp:1:0:
./SanityTest.hpp:14:7: note: ‘SanityTest::SanityTest(SanityTest&&)’ is implicitly deleted because the default definition would be ill-formed:
 class SanityTest
       ^
./SanityTest.hpp:14:7: error: use of deleted function ‘std::atomic_flag::atomic_flag(const std::atomic_flag&)’
In file included from /usr/include/c++/4.8/atomic:41:0,
                 from ./SanityTest.hpp:8,
                 from ./SanityTest.cpp:1:
/usr/include/c++/4.8/bits/atomic_base.h:275:5: error: declared here
     atomic_flag(const atomic_flag&) = delete;
     ^
In file included from /usr/include/c++/4.8/functional:55:0,
                 from /usr/include/c++/4.8/thread:39,
                 from ./SanityTest.hpp:10,
                 from ./SanityTest.cpp:1:
...
In file included from ./SanityTest.cpp:1:0:
./SanityTest.hpp:14:7: note: ‘SanityTest::SanityTest(SanityTest&&)’ is implicitly deleted because the default definition would be ill-formed:
 class SanityTest
       ^
./SanityTest.hpp:14:7: error: use of deleted function ‘std::atomic_flag::atomic_flag(const std::atomic_flag&)’
In file included from /usr/include/c++/4.8/atomic:41:0,
                 from ./SanityTest.hpp:8,
                 from ./SanityTest.cpp:1:
/usr/include/c++/4.8/bits/atomic_base.h:275:5: error: declared here
     atomic_flag(const atomic_flag&) = delete;
     ^
In file included from /usr/include/c++/4.8/functional:55:0,
                 from /usr/include/c++/4.8/thread:39,
                 from ./SanityTest.hpp:10,
                 from ./SanityTest.cpp:1:

附言这是编译的,g++ -pthread -std=c++0x -o SanityTest ./SanityTest.cpp

只需替换

thread SanityTestThread(&SanityTest::_rx, *this);

thread SanityTestThread(&SanityTest::_rx, this);

您可能打算传递指向对象的指针,而不是对象本身(这将导致复制该对象,并且&SanityTest::_rx在该副本而不是原始对象上调用成员函数指针)。

错误消息的原因本质上是std::atomic_flag没有复制构造函数,因此编译器也不会为您的SanityTest类生成默认构造函数,但同样:无论如何,您都不想在此处复制SanityTest对象。