hello guys I have a worker thread in qt with C++ , if I use workerThreadPointer->quit(); in mainwindow destruction ~mainwindow{} or in workerthread destruction its self when I close the program I get this error QThread: Destroyed while thread is still running but if I use workerThreadPointer->terminate(); I wont get any errors but terminate() method is not recommended so how can I use quite on the closing of program with out crashing and getting erorrs
I actually used this and it worked but is it the best way ??
bool asghar;
workerThread::workerThread(){
}
workerThread::~workerThread(){
quit();
requestInterruption();
asghar=0;
wait(100);
}
void workerThread::run(){
asghar=1;
while(asghar==true){
do something
}
}
which is basically I force it to gets out of the while loop with a boolian variable but Im not sure its the best option btw if I change that 100 in wait to 10 , its not ganna work.
I'm not sure if it's a typo because you only wrote pseduo-code or if it's actually like this in your program. But while(asgar=true) doesn't do what you think it does. The classic = vs == bug.
void workerThread::run(){
asghar=1;
while(asghar=true){ // bug
do something
}
Should be this:
void workerThread::run(){
asghar=1;
while(asghar == true) { // fixed
do something
}
Also the compiler is free to optimize away the check to asghar since its access is not thread safe. Consider changing asghar to be of type std::atomic<bool> or wrap the assignment and check calls with a mutex.
Add print/log statement around the assignment and comparison checks to asghar to see what's going on.
Related
I tried to break down my problem to a small example. The real problem is a more complex communication:
I have a function that triggers a communication and connects and sends messages to a server. If there is an answer, the Client-class emits a signal containing the answer.
void communicate()
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
void reactToAnswer(QString answer)
{
parser.parseAnswer() // an error could occur
}
What if an error is detected in the slot in which the response is processed? I would like to stop the execution of the function communicate(). This means that the function client.sendMessage("HelloWorld") should no longer be executed.
In my naivety I tried to handle the problem with exceptions:
void communicate()
{
try
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
catch(myException)
{
// do something
}
void reactToAnswer(QString answer)
{
if( !parser.parseAnswer() )
{
throw myException;
}
}
This does not work, throwing an exception from a slot invoked by a qt-signal is undefined behaviour. The usual way is to reimplement QApplication::notify() resp. QCoreApplication()::notify, but this does not work for me. There is already a QApplication for the GUI and I want the communication class (QObject) to stand alone. All things should be treated within this class.
I hope I explained the problem comprehensibly. I do not want to use exceptions in any case, other ways to stop the communication are also right for me.
Thanks in advance!
I'm not sure that what you are trying to accomplish is a particularly good fit for the signals-and-slots paradigm... perhaps you want to go with just a regular old function call instead? i.e. something like:
void communicate()
{
QString theAnswer; // will be written to by setupMessage() unless error occurs
if (client.setUpMessage(theAnswer))
{
reactToAnswer(theAnswer);
client.sendMessage("HelloWorld");
}
}
The reason that signals-and-slots aren't a good fit is that signals are designed to be connectable to multiple slots at once, and the order in which the slots-methods are called is undefined -- so if a slot-method tries to interfere with the signal-emitting process in the way you describe, the behavior is rather unpredictable (because you don't know how many other connected slot-methods, if any, had already been called as part of the signal-emission, before your particular slot-method hit the brakes). And of course if you ever go to queued/asynchronous signals, then it won't work at all, because the slot will be called in a different context entirely, long after the signal-emitting function has already returned.
That said, if you absolutely must use signals-and-slots for this, you can have your slot emit its own error-has-occurred signal, which can be connected back to a slot in the original signal-emitting class. That slot could then set a boolean (or whatever), and your communicate() method could then check the state of that boolean (right after client.setUpMessage() has returned) to decide whether or not to continue executing or return early.
(I don't recommend that though -- signals-and-slots are there to make your program less complicated, and in this case I think using them instead of a regular function call actually makes your program more complicated, with no corresponding benefit)
When I call joinThread I occasionally get an std::system_error thrown of with "invalid argument" at the join call. The error appears to only show up when I compile with gcc, and it is not consistently reproducible, i.e. it occasionally occurs and not predictably. Does anyone know what could cause such an error?
Below is a reduced version of my code.
class exampleClass
{
public:
exampleClass()
{
}
~exampleClass()
{
joinThread();
}
void doWork()
{
joinThread();
workThread = std::thread(&exampleClass::threadFunction, this);
}
void joinThread()
{
if(workThread.joinable()) workThread.join();
}
protected:
void threadFunction()
{
std::cout << "Do something that requires time..." << std::endl
}
std::thread workThread;
}
Any help would be greatly appreciated.
Since you did not provide an example, where this error occurs, I can only speak from my own experience. There are some things you should consider, in order to avoid such an error:
Is your thread just default constructed, resp. did you initialize it with a valid callback function?
Is your thread detached?
Have you moved your thread?
Is the thread trying to access an already reserved resource? Think about possible deadlock sources! Maybe you got stuck somewhere. (But afaik the thread should still be joinable anyway.)
Does a friend method or class try to access/use/join the thread?
I recently forgot to pass a function to a thread, which I had default constructed in order to use it later. This happened due to a conditional initialization procedure. So regarding your example class above:
Your workThread is default constructed upon constructing an object of exampleClass. A callback function is only passed, if you call doWork(). You have made sure that the thread is only joined, if it is in a joinable state. Upon destruction of your object this is also guaranteed. Thus, the most likely reason I can think of, why this might fail, is if you have somewhere a friend. You haven't put that in your example though, but maybe you neglected this, because you wanted to present a reduced form.
Maybe also a look here: http://cppatomic.blogspot.com/2018/05/modern-effective-c-make-stdthread.html might help.
i am having a bit of a struggle with a mutli-threaded program i am trying to create. Its a pretty simple application im just creating in order to see how multi-threading works and so on :)
okay so the thing is i have 2 threads and 1 variable, Thread1 is supposed to print the variable they have in common once every second or so(time does not really matter, its just an example) then while Thread1 sleeps for 1 second Thread2 comes in and edits its value to something completely different and the next time Thread1 runs its supposed to print the new value assigned by thread2 allthough this is not happening :/ what is happening is that Thread1 prints the default constructors value even tho it got changed, its kind of hard to explain in words so i have linked the simple example below, i am hoping someone can help me understand this. Btw i know i should be using a mutex or a critical section since im sharing a resources between the two, but since they never run at the same time and its just a simple example i just left it out.
Main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
Printer printer;
std::thread thread1(&Printer::SetMessage, printer, printer); //Sets the new value of "New Message"
std::thread thread2(&Printer::Print, printer, &printer); //Prints the message using printf()
while(true) {
Sleep(5000); //i have a beakpoint here just to look at the variables once every 5 sec.
}
return 0;
}
Printer.cpp
void Printer::Print(Printer &obj) {
while(true) {
printf(obj.Message.c_str());
Sleep(1000);
}
}
void Printer::SetMessage(Printer &obj) {
while(true) {
Sleep(10000);
obj.Message = "New Message";
}
}
Printer::Printer(void){
this->Message = "YOLO";
}
Printer::~Printer(void){}
so i simply want the value of Message to get updated in all other threads, i mean they are using the same object and changing the value in the same damn object, but why will it not stay changed between threads ??? im so confused :S i have only seen examples that do it in the same class, it got so much more complicated(in my brain) once i used multiple classes.
You pass printer to the thread constructor, which copies the object, so each thread has a different Printer, not the same object.
In fact, your code shouldn't even compile, but std::thread in Visual Studio has a bug that allows this to happen (and that's ignoring the fact you wrote &printer which would pass a pointer, and Printer::print(Printer& obj) doesn't take a pointer).
To pass a reference to the thread function you need to wrap the object using std::ref which creates a reference_wrapper<Printer> that forwards the argument as a reference to the new thread, instead of making a copy and passing the copy to the new thread:
std::thread thread2(&Printer::Print, std::ref(printer), std::ref(printer));
However, even if you fix that, your code has undefined behaviour, because it is unsafe and invalid for two threads to read/write the same memory location without using mutexes or atomic operations to do the updates safely.
Btw i know i should be using a mutex or a critical section since im sharing a resources between the two, but since they never run at the same time and its just a simple example i just left it out.
Perhaps the thing you've missed is that even though you put sleep instructions in each method in the hope that each thread would be only active while the other is sleeping, there are no guarantees that the program will execute that way.
The only safe way of blocking a thread while the other is active is to coordinate them using a lock.
You should also pass the data by reference to the threads.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a QThread running some code and I wanted it to do exit nicely and do some cleanings so the code goes as:
testdevice.h
class testDevice : public QThread
{
Q_OBJECT
... // some definitions
protected:
void run(void);
private:
hid_device *handle;
bool abort;
public:
~testDevice(void);
};
testdevice.cpp
testDevice::~testDevice(void)
{
mutex.lock();
abort = true;
mutex.unlock();
wait();
if (handle != NULL)
{
hid_close(handle);
}
hid_exit();
}
void testDevice::run(void)
{
while(true)
{
mutex.lock();
if(abort)
{
return;
}
mutex.unlock();
if (_connected)
{
//... more code
}
else // Case device is not connected
{
emit deviceConnected(_connected);// A breakpoint in here is not triggered after abort is true
handle = hid_open(TEST_VID, TEST_PID, NULL); // this is where VS2010 shows the error "Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation."
//...code continues
The behaviour I was expecting was run() to be called and when ~testDevice() destructor is called abort is set to true and wait blocks the destructor, and runreturns and then the destructor continues.
What is happening is that run() is called and when I close the application the destructors ~testDevice() is called and abort is set to true and wait() returns and the destructor finishes...BUT then run() keeps running and I get Unhandled exception at 0x71241a95 in project.exe: 0xC0000005: Access violation.....I am running this as VS2010 debug, if I place breakpoints I get this all the time, but with no breakpoints I just got this once in a while...any clues?
Something weird is that when I place a breakpoint in abort = true; sometimes the first breakpoint that hits in there has a small blue '!' sign, and the second time it hits is a regular all red one. The same happens for the breakpoint at emit deviceConnected(_connected); but this is kinda random as well...I dont know what this '!' means...could all of this be a debug problem?
My general suspicion is that HIDAPI is running in a separate thread and it has its own bugs when someone call hid_exit(); maybe hid_read(); continues to run and since hid_quit(); was called, hid_read(); looses some pointers and doesnt close...just a wild shot and to confirm this I need some developer at the HIDAPI to come foward and say something...I hope they read this
You seem to be using QThread in a custom way rather than the usual start() and quit() execution. The best would be that in an ideal world if you could refactor your code using quit() for quiting a QThread since that would be closer to the signal/slot mechanism of this QObject subclass.
However, I agree that it is not always possible. I cannot yet tell you based on your few lines you provided that it would make sense in this particular case, but at least I would encourage you to think about it.
Also, you could possibly use the QWaitCondition for waiting for something to happen rather than low-level or/and custom wait() calls.
As for quickly working around the issue you are facing if the issue at hand is compiler optimization of a boolean value like putting it into the cache, you could try having making it atomic by using the std::atomic (C++11) or QAtomicInt option. This will make sure that the compiler cannot optimize the reads and writes out.
You would write something like this with the std typedef:
std::atomic_bool abort;
If you need to support pre C++-11 compilers as well as Qt 4, you would use the Qt class like this:
QAtomicInt abort;
I have a program that uses boost threads. The program has start and stop functionality. When the program is started I create a boost thread that does some processing. When the program is stopped I call join on this thread and delete the thread's pointer. My program starts and stops correctly the first time; however, when I try to start my program a second time I fail an assertion inside of boost (when newing the processing thread) and the following is output on my screen
/root/src/boost.cmake/libs/thread/src/pthread/once.cpp:46: unsigned long &boost::detail::get_once_per_thread_epoch(): Assertion`!pthread_setspecific(epoch_tss_key,data)' failed.
I know that my join is working correctly because when the processing thread exits I output a message to my console. Does anyone know why this might happen?
An extra note... I have played around with my code a little bit and the methodology that I am using to clean up my boost threads appears to work in other parts of my program (for example, if I create the boost::thread in the parent class). However, it fails every time in the child class (which is an abstract class).
My start and stop methods looks like this...
void ThreadMethod()
{
while(_runningThread)
{
}
}
void Start()
{
_runningThread = true;
_thread = boost::make_shared<boost::thread>(&TestChildVirtualClass::ThreadMethod, this);
};
void Stop()
{
_runningThread = false;
_thread->join();
if( _thread )
{
_thread.reset();
}
};
However, I am having trouble recreating this issue in a test program (although it occurs every time in my actual program).
The error could be a bug on Boost.Thread as there are some holes in the call_once implementation (#5752 boost::call_once() is unreliable on some platforms - see https://svn.boost.org/trac/boost/ticket/5752). This of course depends on which platform you are running your program.
Of course I maybe wrong.
You should also protect the access to _runningThread.