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.
Related
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.
I have a worker thread that is constantly running, created & managed through a std::thread. At the top level of my worker thread, I have a try/catch block with a while loop inside it. If an exception leaks through to the top level of the thread, I catch it and store it in a std::exception_ptr, which is a member of the class that also owns the non-static thread function:
// In class header (inside class declaration)
std::exception_ptr m_threadException;
// In class CPP file
void MyClass::MyThreadFunction()
{
try {
while (true) {
// Do thread stuff
}
}
catch (std::exception const& e) {
m_threadException = std::current_exception();
}
}
Once the thread dies due to this kind of exception, my class (which is also primarily used by the main thread) doesn't know it yet. My plan was to add thread checkpoints to the start of all the class's main functions, like so:
void MyClass::SomethingMainThreadCalls()
{
if (m_threadException) {
std::rethrow_exception(m_threadException);
m_threadException = nullptr; // Somehow reset it back to null; not sure if this will work
}
// Do normal function stuff
}
Assuming this is even a good idea, there's a possible race condition between when my main thread is checking if the exception_ptr is null (when calling SomethingMainThreadCalls()) and when the worker thread assigns to it. I haven't found any information (haven't checked the C++11 draft yet) about whether or not this is inherently thread safe (guaranteed by the standard) or if I am responsible for thread synchronization in this case.
If the latter, is using std::atomic a good idea to keep it simple? Example:
std::atomic<std::exception_ptr> m_threadException;
Something like that? I'd be interested in recommendations and information on best practice here.
There is no special statement about exception_ptr with regards to its thread safety in the standard. As such, it provides the default standard guarantee: accessing separate instances are fine, accessing the same instance is not.
I would suggest using atomic<bool> instead (if for no other reason than that exception_ptr is not trivially copyable and therefore can't be put in an atomic<T>) to let the other code know that the exception_ptr has been set. You'll be fine so long as:
You set m_threadException before setting the flag
You read m_threadException after checking the flag
You use the appropriate load/store memory orders to set/check the flag. The defaults are fine
You only write m_threadException exactly once.
The standard doesn't specify what is the implementation of std::exception_ptr, so the thread safeness of std::exception_ptr is also unspecified.
just wrap the exception pointer with some lock and the code will be fine.
Just tried to do this, but std::atomic requires a trivially copyable type, std::exception_ptr is not. You should get compilation error as I do (when using MSVC VS2019, C++14).
I'm using boost to start a thread and the thread function is a member function of my class just like this:
class MyClass {
public:
void ThreadFunc();
void StartThread() {
worker_thread_ = boost::shared_ptr<boost::thread>(
new boost::thread(boost::bind(&MyClass::ThreadFunc, this)));
}
};
I will access some member variables in ThreadFunc:
while (!stop) {
Sleep(1000); // here will be some block operations
auto it = this->list.begin();
if (it != this->list.end())
...
}
I can not wait forever for thread return, so I set timeout:
stop = true;
worker_thread_->interrupt();
worker_thread_->timed_join(boost::posix_time::milliseconds(timeout_ms));
After timeout, I will delete this MyClass pointer. Here will be a problem, the ThreadFunc hasn't return, it will have chances to access this and its member variables. In my case, the iterator will be invalid and it != this->list.end() will be true, so my program will crash if using invalid iterator.
My question is how to avoid it ? Or how to check whether this is valid or member variables is valid ? Or could I set some flags to tell ThreadFunc the destructor has been called ?
There are a lot of possible solutions. One is to use a shared_ptr to the class and let the thread hold its own shared_ptr to the class. That way, the object will automatically get destroyed only when both threads are done with it.
How about you create a stopProcessing flag (make it atomic) as a member of MyClass and in your ThreadFunc method check at each cycle if this flag is set?
[EDIT: making clearer the answer]
There a two orthogonal problems:
stopping the processing (I lost my patience, stop now please). This can be arranged by setting a flag into MyClass and make ThreadFunc checking it as often as reasonable possible
deallocation of resources. This is best by using RAII - one example being the use of shared_ptr
Better keep them as separate concerns.
Combining them in a single operation may be possible, but risky.
E.g. if using shared_ptr, the once the joining thread decided "I had enough", it simply goes out of the block which keeps its "copy" of shared_ptr, thus the shared_ptr::use_count gets decremented. The thread function may notice this and decide to interpret it as an "caller had enough" and cut short the processing.However, this implies that, in the future releases, nobody else (but the two threads) may acquire a shared_ptr, otherwise the "contract" of 'decremented use_count means abort' is broken.
(a use_count==1 condition may still be usable - interpretation "Only me, the processing thread, seems to be interested in the results; no consumer for them, better abort the work").
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.
I am trying to do the followings
class a{
public:
void Start();
void Tick();
bool IsTimeOut;
};
void a::Start()
{
boost::thread thread1(boost::bind(&a::Tick,this));
}
void a::Tick()
{
while(!IsTimeOut)
{
boost::this_thread::sleep(boost::posix_time::millisec(1000));
}
}
My environment is vs2005 and win7.
However, I always got the access violation in the debug.
An access violation in this case would indicate that the thread is running beyond the lifetime of the a object.
IsTimeOut needs to either be atomic or protected by a mutex if it is written by another thread, otherwise your program might not work correctly, but this shouldn't cause the access violation.
You are destroying the boost::thread object immediately, and thus detaching the thread, so you have no way of waiting for it to finish. I would suggest storing the thread object as a member variable of a, and either joining with it in the destructor of a or providing an explicit wait() member function that joins with the thread.
IsTimeOut should be volatile if accessed from multiple threads, i.e.
volatile bool IsTimeOut;
Take a look at this DDJ article.
If you show more of your code and also explain how the IsTimeOut is changed it might be easier to say what goes wrong. In general, it looks like you have multiple threads and the first creates a, but what does that thread do then? Will a go out of scope and thus be destroyed? If so, then the timer thread will for sure have an access violation as the object is no longer available.