這是對a question I got answered yesterday的跟進。指向成員對象的指針 - 中斷線程
我試圖讓成員函數中斷線程,但我不知道是什麼,這些錯誤是:
[[email protected] projects]$ g++ -o test test.cpp -lpthread
test.cpp: In instantiation of ‘InterruptibleThread::InterruptibleThread(Function&&, Args&& ...)::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, Args&& ...)> [with auto:1 = void (MyClass::*)(int); Function = void (MyClass::*)(int); Args = {MyClass*, int}; std::atomic_bool = std::atomic<bool>]’:
/usr/local/include/c++/6.3.0/type_traits:2481:26: required by substitution of ‘template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, MyClass*&&, int&&)>; _Args = {std::reference_wrapper<std::atomic<bool> >, std::reference_wrapper<std::atomic<bool> >, void (MyClass::*)(int), MyClass*, int}]’
/usr/local/include/c++/6.3.0/type_traits:2492:55: required from ‘struct std::__result_of_impl<false, false, InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, MyClass*&&, int&&)>, std::reference_wrapper<std::atomic<bool> >, std::reference_wrapper<std::atomic<bool> >, void (MyClass::*)(int), MyClass*, int>’
/usr/local/include/c++/6.3.0/type_traits:2496:12: required from ‘class std::result_of<InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, MyClass*&&, int&&)>(std::reference_wrapper<std::atomic<bool> >, std::reference_wrapper<std::atomic<bool> >, void (MyClass::*)(int), MyClass*, int)>’
/usr/local/include/c++/6.3.0/functional:1365:61: required from ‘struct std::_Bind_simple<InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, MyClass*&&, int&&)>(std::reference_wrapper<std::atomic<bool> >, std::reference_wrapper<std::atomic<bool> >, void (MyClass::*)(int), MyClass*, int)>’
/usr/local/include/c++/6.3.0/thread:137:26: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]::<lambda(std::atomic_bool&, std::atomic_bool&, auto:1&&, MyClass*&&, int&&)>; _Args = {std::reference_wrapper<std::atomic<bool> >, std::reference_wrapper<std::atomic<bool> >, void (MyClass::*)(int), MyClass*, int}]’
test.cpp:41:33: required from ‘InterruptibleThread::InterruptibleThread(Function&&, Args&& ...) [with Function = void (MyClass::*)(int); Args = {MyClass*, int}]’
test.cpp:111:53: required from here
test.cpp:36:9: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fxn (...)’, e.g. ‘(... ->* fxn) (...)’
fxn(forward<Args>(args)...);
當前代碼:
using namespace std;
class InterruptThreadException {};
class InterruptibleThread {
private:
static thread_local atomic_bool* stopRef;
static thread_local atomic_bool* pauseRef;
atomic_bool stopFlag{false};
atomic_bool pauseFlag{false};
thread thrd;
public:
friend void checkForInterrupt();
template < typename Function, typename... Args >
InterruptibleThread(Function&& _fxn, Args&&... _args)
: thrd(
[](atomic_bool& sr, atomic_bool& pr, auto&& fxn, Args&&... args) {
stopRef = &sr;
pauseRef = ≺
fxn(forward<Args>(args)...);
},
ref(stopFlag),
ref(pauseFlag),
forward<Function>(_fxn),
forward<Args>(_args)...) {
thrd.detach();
}
bool stopping() const {
return stopFlag.load();
}
void stop() {
stopFlag.store(true);
}
void pause() {
pauseFlag.store(true);
cout << "setting pause flag: " << pauseFlag.load() << endl;
}
void start() {
pauseFlag.store(false);
}
};
void checkForInterrupt() {
cout << "Pause flag: " << InterruptibleThread::pauseRef->load() << endl;
cout << "Stop flag: " << InterruptibleThread::stopRef->load() << endl;
while (InterruptibleThread::pauseRef->load()) {
cout << "Paused\n";
this_thread::sleep_for(chrono::seconds(1));
}
if (!InterruptibleThread::stopRef->load()) {
return;
}
throw InterruptThreadException();
}
thread_local atomic_bool* InterruptibleThread::stopRef = nullptr;
thread_local atomic_bool* InterruptibleThread::pauseRef = nullptr;
void doWork() {
int i = 0;
try {
while (true) {
cout << "Checking for interrupt: " << i++ << endl;
checkForInterrupt();
this_thread::sleep_for(chrono::seconds(1));
}
} catch (InterruptThreadException) {
cout << "Interrupted\n\n";
}
}
class MyClass {
private:
int myInt;
void setInt(int i) {
myInt = i;
}
public:
MyClass() : myInt(1) {
}
void myWork(int i);
void doWork();
};
void MyClass::myWork(int i) {
setInt(i);
cout << "myInt value: " << myInt << endl;
}
void MyClass::doWork() {
InterruptibleThread t(&MyClass::myWork, this, 666);
}
int main() {
MyClass mc;
mc.doWork();
cout << "Press enter to exit" << endl;
getchar();
return 0;
}
我試過編譯器的建議,得到了之後的錯誤與fold表達式有關(afaik是C++ 17,我不會使用超過14的任何東西)。任何想法如何讓這個工作?
我有一個沒有使用lambdas的工作版本,但我真的好奇如何讓這與原始代碼一起工作。
它在我看來像你的編譯器不滿意你的'類interruptiblethread'的定義中的'靜態'修飾符。你能把這些拿出來嗎?只是爲了看看它是否有幫助? –
你是指靜態thread_locals?如果是這樣,thread_locals無論如何都是隱式靜態的,但某些編譯器不會明確地靜態聲明編譯(有人糾正我,如果我錯了,但我的不會) – user1324674