Dies ist eine Folge zu a question I got answered yesterday.Zeiger auf Elementobjekt - Interrupt Thread
Ich versuche, einen Interrupt-Thread für Member-Funktionen zu machen, aber ich habe keine Ahnung, was diese Fehler sind:
[[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)...);
Aktuelle Code:
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;
}
ich den Compiler Vorschlag versucht und bekam ein Fehler im Nachhinein, der sich auf Faltexpression bezieht (die afaik sind C++ 17 und ich soll nichts außer 14 verwenden). Irgendeine Idee, wie man das zur Arbeit bringt?
Ich habe eine funktionierende Version von diesem ohne Lambdas zu verwenden, aber ich bin wirklich neugierig, wie man das mit dem ursprünglichen Code arbeiten lässt.
Es sieht für mich so aus, als wäre Ihr Compiler nicht zufrieden mit den 'statischen' Modifikatoren in der Definition für Ihre 'Klasse interruptiblethread'. Kannst du die rausnehmen? Nur um zu sehen, ob es hilft? –
Beziehen Sie sich auf die statischen thread_locals? Wenn ja, thread_locals sind implizit statisch, aber bestimmte Compiler kompilieren nicht ohne die statische Deklaration explizit (jemand korrigiert mich, wenn ich falsch liege, aber meins wird) – user1324674