I'm learning about multithreading and I wrote this code:
#include <iostream>
#include <mutex>
#include <thread>
#include <string>
#include <chrono>
#include <condition_variable>
int distance = 20;
int distanceCovered = 0;
std::condition_variable cv;
std::mutex mu;
void keep_moving(){
while(true){
std::cout << "Distance is: " << distanceCovered << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
distanceCovered++;
if(distanceCovered == distance){
cv.notify_one();
std::terminate();
}
}
}
void wake_me_up()
{
std::unique_lock<std::mutex> ul(mu);
cv.wait( ul, []{ return distanceCovered==distance; }); // protects the lines of code below
std::cout << "I'm here" << std::endl;
std::terminate();
}
int main() {
std::thread driver(keep_moving);
std::thread wake_me(wake_me_up);
driver.join();
wake_me.join();
system("pause");
return 0;
}
As you can see thread 'keep_moving' counts from 0-20 in 20 seconds and then notifies the 'wake_me_up' thread which prints "I'm here" and then terminates. After notifying the thread the 'keep_moving' thread also terminates.
Please tell me if I'm terminating the threads in a proper way. When I run this code I get the following message:
terminate called without an active exception
I'm here
terminate called recursively
Aborted
Thank you.
No. The correct (and only correct in standard C++) way to terminate a thread is to return from its thread function.
std::terminate kills your entire process. Even if it only killed the current thread (i.e. behaved like the Win32 TerminateThread function, which you should never call!), it would not unwind the stack, not call destructors, and thus possibly leave some necessary cleanup unfinished (like releasing mutexes).
std::terminate is meant to be used on a critical failure where your program cannot possibly continue. The message "without an active exception" is because the primary use of terminate is to kill the program if the exception system fails, e.g. due to a nested exception, so the function by default looks for an active exception and prints information about it.
Related
I was expecting that the status of sub-thread, whether they succeed or not, should not crash main thread.
So I had a quick test:
#include <thread>
#include <iostream>
#include <exception>
using namespace std;
using namespace std::chrono;
void th_function() {
this_thread::sleep_for(chrono::seconds(2));
throw 1; // the criminal here!
}
int main() {
auto th = thread{ th_function };
this_thread::sleep_for(chrono::seconds(1));
cout << "1" << endl;
th.join();
cout << "2" << endl;
return 0;
}
The running result is:
1
Program stderr
terminate called after throwing an instance of 'int'
Well, seems the throw 1 call leads to main thread crash. I think for c++, each thread has its own runtime stack and exception-process chain.
Then why in my case, sub-thread exception will terminate main thread?
Thanks.
It is true that exceptions handling is localized to a single thread, but as always, not catching an exception at all causes a call to std::terminate, which in turn terminates the whole program. The same applies to other conditions resulting in a call to std::terminate, e.g. throwing from a destructor during stack unwinding or letting an exception escape a noexcept function. These are all considered unrecoverable errors.
You can use e.g. std::async if you need to continue execution after an unhandled exception in the thread. std::async includes functionality to catch otherwise uncaught exceptions and stores/forwards them in a std::future, so that the main thread can receive them.
I'm new to C++ and I'm trying to make the console print "after 5 seconds" after 5000 ms. Then print "insta log" immediately after the new thread's declaration.
But doing so crashes with the following error:
"Debug Error!
[PROGRAM PATH]
abort() has been called
"
This is my code:
#include <iostream>
#include <thread>
#include <Windows.h>
#include <ctime>
using namespace std;
void f() {
Sleep(5000);
cout << "after 5 seconds" << endl;
}
int main() {
cout << "starting" << endl;
// Pass f and its parameters to thread
// object constructor as
thread t(&f);
cout << "insta log" << endl;
}
I'm unsure why this is happening. I've searched around and I found a "fix" but it makes my code not behave as intended.
This is the "fix"
#include <iostream>
#include <thread>
#include <Windows.h>
#include <ctime>
using namespace std;
void f() {
Sleep(5000);
cout << "after 5 seconds" << endl;
}
int main() {
cout << "starting" << endl;
// Pass f and its parameters to thread
// object constructor as
thread t(&f);
t.join();
cout << "insta log" << endl; // doesn't print for 5 seconds
}
This removes the error message but yields the main thread for 5 seconds. Which makes my code not work as intended.
Thanks in advance, any help is appreciated!
This removes the error message.
Yes.
but yields the main thread for 5 seconds.
This is not what is happening!
The main thread is waiting for your second thread t to finish (slightly different to yielding).
The problem before was that the main thread was exiting the application (and you are not allowed to have other threads running after the main thread exits (this is because what happens to the children thread is highly depended on the threading implementation and they very wildly).
In the C++ std::thread class they try and compensate for the above behavior by making the destructor terminate() if the current thread leaves scope without the child thread of execution completing.
This means you usually have to call the join() method to wait for the child to exit.
So what you usually do is 1: create a std::thread object that does some work in the background 2: while you do some work locally. Then when you have finished, 3: you call join() and wait for the child object to also finish (if it has already finished this does nothing). Then you can exit scope (and exit the main).
Which makes my code not work as intended.
int main()
{
// STUFF.
// Create your thread.
thread t(&f);
// Print any thing you want.
// i.e. do the work you want to do in main.
cout << "insta log" << endl;
// When you have finished.
// wait for the child to finish.
t.join();
} // now the std::thread::~thread check to make sure the
// child thread of execution is no longer running.
If you had clicked 'retry' in that dialog you would have seen why your code died. Its right here
~thread() noexcept {
if (joinable()) {
_STD terminate();
}
}
in the MSVC implementation of std::thread. The code says that destroying a thread thats still joinable (ie is running) is illegal. I dont know if thats c++ defined behavior, a quick search didnt show me. Anyway when you join the thread, you will wait till its OK to destroy it
Functions are already passed around as pointers, use thread t(f) instead of thread t(&f).
Moreover, since your main() neither lasts longer than the thread or calls a t.join(), the program will end before the thread finishes it's code, so that might be another reason for a crash. In fact it is probably the reason for the crash.
If you want "insta log" to print instantly, then call t.join() at the end of main(). t.join() will wait for the thread t to end before continuing.
The following code is from modernescpp. I understand that when the lock_guard in the main thread holding the mutex causes the deadlock. But since the created thread should start to run once it is initialized. Is there a chance that after line 15 the functions lock_guard on line 11 already grabbed coutMutex so the code runs without any problem? If it is possible, under what circumstance the created thread
will run first?
#include <iostream>
#include <mutex>
#include <thread>
std::mutex coutMutex;
int main(){
std::thread t([]{
std::cout << "Still waiting ..." << std::endl;
std::lock_guard<std::mutex> lockGuard(coutMutex); // Line 11
std::cout << std::this_thread::get_id() << std::endl;
}
);
// Line 15
{
std::lock_guard<std::mutex> lockGuard(coutMutex);
std::cout << std::this_thread::get_id() << std::endl;
t.join();
}
}
Just so the answer will be posted as an answer, not a comment:
No, this code is not guaranteed to deadlock.
Yes, this code is quite likely to deadlock.
In particular, it's possible for the main thread to create the subordinate thread, and then both get suspended. From that point, it's up to the OS scheduler to decide which to run next. Since the main thread was run more recently, there's a decent chance it will select the subordinate thread to run next (assuming it attempts to follow something vaguely like round-robin scheduling in the absence of a difference in priority, or something similar giving it a preference for which thread to schedule).
There are various ways to fix the possibility of deadlock. One obvious possibility would be to move the join to just outside the scope in which the main thread holds the mutex:
#include <iostream>
#include <mutex>
#include <thread>
std::mutex coutMutex;
int main(){
std::thread t([]{
std::cout << "Still waiting ..." << std::endl;
std::lock_guard<std::mutex> lockGuard(coutMutex); // Line 11
std::cout << std::this_thread::get_id() << std::endl;
}
);
// Line 15
{
std::lock_guard<std::mutex> lockGuard(coutMutex);
std::cout << std::this_thread::get_id() << std::endl;
}
t.join();
}
I'd also avoid locking a mutex for the duration of using std::cout. cout is typically slow enough that doing so will make contention over the lock quite likely. It's typically doing to be better to (for only one example) format the data into a buffer, put the buffer into a queue, and have a single thread that reads items from the queue and shoves them out to cout. This way you only have to lock for long enough to add/remove a buffer to/from the queue.
Two thread. Main one is constantly gathering notifications while the other one is processing some of them.
The way i implemet it - is not correct as i've been told. What problems is it causing and what's wrong about it?
#include <iostream>
#include <atomic>
#include <thread>
#include <mutex>
#include <chrono>
std::condition_variable foo;
std::mutex mtx;
void secondThread()
{
while (true)
{
foo.wait(std::unique_lock<std::mutex>(mtx));
std::cout << " ----------------------------" << std::endl;
std::cout << "|processing a notification...|" << std::endl;
std::cout << " ----------------------------" << std::endl;
}
}
int main()
{
std::thread subThread = std::thread(&secondThread);
int count = 0;
while (true)
{
if (count % 10 == 0)
{
foo.notify_one();
}
std::cout << "Main thread working on gathering notifications..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(300));
count++;
}
return 0;
}
I was told that this foo.wait(std::unique_lock<std::mutex>(mtx)) line of code is not a good practice according to the C++ spec. This is not a proper way of solving this kind of problem. It's also called, sleeping(not busy waiting).
Before you call wait, you must check that the thing you are waiting for hasn't already happened. And before you stop calling wait, you must check that the thing you are waiting for has happened. Condition variables are stateless and have no idea what you're waiting for. It's your job to code that.
Also, the associated mutex must protect the thing you're waiting for. The entire point of a condition variable is to provide an atomic "unlock and wait" operation to prevent this problem:
You check if you need to wait under the protection of a mutex.
You decide you do need to wait.
You unlock the mutex so other threads can make progress.
You wait.
But what if the thing you're waiting for happens after you unlocked the mutex but before you waited? You'll be waiting for something that already happened.
This is why the wait function takes a lock holder -- so that it can perform steps 3 and 4 atomically.
I know many people asked this question, but im not "many people" and I need a different and a better explanation to understand.
The member function "detach()" what exactly it does?
I tried running the next code sample:
#include <iostream>
#include <chrono>
#include <thread>
void independentThread()
{
std::cout << "Starting concurrent thread.\n";
std::this_thread::sleep_for(std::chrono::seconds(200));
std::cout << "Exiting concurrent thread.\n";
}
void threadCaller()
{
std::cout << "Starting thread caller.\n";
std::thread t(independentThread);
t.detach();
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Exiting thread caller.\n";
}
int main()
{
threadCaller();
std::this_thread::sleep_for(std::chrono::seconds(5));
}
And after 5 seconds the all program closed.
I thought the program will be opened another 195 seconds after the "main" closes, because the all idea of "detach" is that is independent with the main, so in independent way, it should still run untill the all detached therades are terminates...
I read the documentation and came to here.
A better explanation - PLEASE! :)
Detached thread is a thread you can't wait on to complete. std::thread destructor will check if the thread is either detached or joined, and if neither happened, will abort a program (call std::terminate).
After the main() terminates, program unconditionally terminates as well, not waiting for any threads, detached or otherwise.