Speicherzugriffsfehler bei Programm mit std::thread
-
Hallo Community,
für ein Projekt im Studium habe ich mit Kommilitonen ein Programm in C++ geschrieben.
Das Programm soll später auf einem Raspberry Pi mit Raspian laufen, aber zum Testen arbeite ich gerade auf einer Virtuellen Maschine mit Ubuntu.Das Programm arbeitet auf den ersten Blick fehlerlos. Aber wenn ich es mit Strg + D beende, kommt die Meldung:
Ubuntu schrieb:
speicherzugriffsfehler (speicherabzug geschrieben)
Leider kommt die Meldung nicht immer. Es kann 100 mal gut gehen, aber sobald sie ein mal da war, kommt sie jedes mal (aber nur beim Beenden).
Meine Vermutung ist, dass es an meiner Verwendung von std::thread liegt. Ich habe mal eine Beispiel geschrieben, dass thread so verwendet wie mein Programm:
#include <chrono> #include <iostream> #include <thread> using namespace std; using namespace std::chrono; class ThreadTester { public: ThreadTester() { thread(&ThreadTester::test, this).detach(); } void test() { while (true) { this_thread::sleep_for(seconds{1}); cout << "test\n"; } } }; int main() { ThreadTester tester; for (char c; cin >> c;); return 0; }
Leider ist es mir nicht gelungen, den Fehler damit zu reproduzieren. Wie gesagt, es geht auch mit meinem Programm lange gut.
valgrind --leak-check=all -v ./test liefert mir:
valgrind schrieb:
==18399== 288 bytes in 1 blocks are possibly lost in loss record 2 of 2
==18399== at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18399== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==18399== by 0x5359DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==18399== by 0x4EE8E3E: std::thread::_M_start_thread(std::shared_ptrstd::thread:\_Impl\_base) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==18399== by 0x401507: std::thread::thread<void (ThreadTester::)(), ThreadTester const>(void (ThreadTester::&&)(), ThreadTester const&&) (in /home/matze/test/test)
==18399== by 0x40135D: ThreadTester::ThreadTester() (in /home/matze/test/test)
==18399== by 0x401030: main (in /home/matze/test/test)Auch bei meinem eigentlichen Programm meckert valgrind nur über die threads (daher auch meine Vermutung).
Compiler ist g++ 4.8.2
Das Beispiel muss ich mit -pthread kompilieren, weil ich sonst einen Laufzeitfehler bekomme:Ubuntu schrieb:
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
Abgebrochen (Speicherabzug geschrieben)Das ist mir bei meinem eigentlichen Programm nicht passiert
Oder bin ich mit den threads total auf dem Holzweg und es liegt wahrscheinlich an etwas völlig Anderem?
Ich wäre für jede Hilfe dankbar.
Viele Grüße
Matze
-
Bevor du das Programm beendest, musst du sicherstellen, dass alle anderen Threads auch beendet wurden. Sonst laufen die munter weiter, während sich das Programm gerade abbaut.
-
Hallo,
ja, mir ist auch gerade aufgefallen, dass die Destruktoren der thread-lokalen Objekte gar nicht aufgerufen wurden.
Ich versuche das mal mit join im Destruktor und melde mich dann wieder.
Gruß
Matze
-
Ich habe das jetzt so gelöst:
#include <chrono> #include <iostream> #include <thread> using namespace std; using namespace std::chrono; class ThreadTester { public: ThreadTester() : run{ true }, myThread{ &ThreadTester::test, this } {} ~ThreadTester() { run = false; myThread.join(); } void test() { while (run) { this_thread::sleep_for(seconds{1}); cout << "test\n"; } } private: bool run; thread myThread; }; int main() { ThreadTester tester; for (char c; cin >> c;); return 0; }
Das scheint zu funktionieren. Alle Konstruktoren werden aufgerufen.
Die Fehlermeldung aus meinem ersten Post habe ich seit 2.5h nicht gesehen. Wahrscheinlich kommt der erst wieder bei der PräsentationIst das oben so ok, oder kann mir das wieder um die Ohren fliegen?
Muss ich aus dem run ein atomic<bool> machen?Vielen Dank und viele Grüße
Matze
-
MatzeHHC schrieb:
Muss ich aus dem run ein atomic<bool> machen?
Ja!
-
manni66 schrieb:
MatzeHHC schrieb:
Muss ich aus dem run ein atomic<bool> machen?
Ja!
Ok!