Reputation: 201
I want to make an application that listens for some kind of input constantly, without pauses (delaying the read, misses the message) and writing the message to a database (which in my case takes 60ms).
My idea is to have the listening function threaded (or not) in a while(1)
loop, which adds to an array/vector of structs (in the below code it is a single variable int newValues
) and then check if there is a message available and spawn a thread to deal with it. I also tried to spawn a thread from the listening function for every received message (which is the preferable method, but I don't know if I can spawn infinite threads) but both times the program terminates with: pure virtual method called
. I found out that it means that a member of a destructed object is called, but this doesn't help me understand why the below code doesn't work:
#include <iostream>
#include <thread>
using namespace std;
int newValues; //if this is under 20 then it should be displayed
void listen();
void available();
int main() {
while (1) {
//constantly listen
//this works for a little longer if is called without a thread
thread lis(listen);
lis.detach();
if (newValues < 20) { //if needed display it
thread ava(available); //without disrupting the listening
ava.detach();
}
}
return 0;
}
void listen() {
newValues = rand() % 100;
}
void available() {
cout << newValues << endl;
}
The output from gdb is:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0x76bb2450 (LWP 19329)]
[New Thread 0x763b2450 (LWP 19330)]
[Thread 0x76bb2450 (LWP 19329) exited]
[Thread 0x763b2450 (LWP 19330) exited]
[New Thread 0x76bb2450 (LWP 19331)]
[Thread 0x76bb2450 (LWP 19331) exited]
[New Thread 0x763b2450 (LWP 19332)]
[Thread 0x763b2450 (LWP 19332) exited]
[New Thread 0x76bb2450 (LWP 19333)]
15
[New Thread 0x763b2450 (LWP 19334)]
[Thread 0x763b2450 (LWP 19334) exited]
[New Thread 0x75bb2450 (LWP 19335)]
pure virtual method called
terminate called without an active exception
[New Thread 0x763b2450 (LWP 19336)]
[New Thread 0x753b2450 (LWP 19337)]
pure virtual method called
terminate called recursively
[Thread 0x763b2450 (LWP 19336) exited]
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x75bb2450 (LWP 19335)]
0x76bf3f50 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/pi/smart_home/mw_0.1/RPi/nRF24/thread
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0x76bb2450 (LWP 19341)]
[New Thread 0x763b2450 (LWP 19342)]
[Thread 0x76bb2450 (LWP 19341) exited]
[Thread 0x763b2450 (LWP 19342) exited]
[New Thread 0x76bb2450 (LWP 19343)]
pure virtual method called
terminate called without an active exception
[New Thread 0x763b2450 (LWP 19344)]
[New Thread 0x75bb2450 (LWP 19345)]
[Thread 0x763b2450 (LWP 19344) exited]
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x76bb2450 (LWP 19343)]
0x76bf3f50 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
The output from the actual application:
[New Thread 0x75bb2450 (LWP 19686)]
pure virtual method called
terminate called without an active exception // <- difference
[New Thread 0x753b2450 (LWP 19687)]
[New Thread 0x74bb2450 (LWP 19688)]
pure virtual method called
[Thread 0x753b2450 (LWP 19687) exited]
Program received signal SIGABRT, Aborted.
[Switching to Thread 0x75bb2450 (LWP 19686)]
0x76bf3f50 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
But the idea is the same and the code won't work on another machine.
How can I make this work?
Upvotes: 0
Views: 861
Reputation: 354
To your comment, you have a data race on newValues
with infinite threads, which is undefined behavior. You need some kind of synchronization (a mutex or an atomic data type).
Upvotes: 3