Проблема с использованием std::atomic_flag с рабочим потоком
Извините за многословие - я приложил все усилия, чтобы сжать мой пример кода в минимально функциональный класс и 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:
PS Это скомпилировано, g++ -pthread -std=c++0x -o SanityTest ./SanityTest.cpp
1 ответ
Просто замени
thread SanityTestThread(&SanityTest::_rx, *this);
с
thread SanityTestThread(&SanityTest::_rx, this);
Вы, вероятно, намеревались передать указатель на объект, а не сам объект (что привело бы к копированию этого объекта и указателя на функцию-член). &SanityTest::_rx
вызывается на этой копии вместо исходного объекта).
Причина сообщения об ошибке заключается в том, что std::atomic_flag
не имеет конструктора копирования, и поэтому компилятор не генерирует конструктор по умолчанию для вашего SanityTest
Класс, но опять же: вы не хотите копировать ваш объект SanityTest здесь в любом случае.