What "detach()" on thread does? CPP - c++

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.

Related

My code is exiting with use-after-free error but I don't know why?

I'm a multithreading beginner and I'm wring the below code:
#include <iostream>
#include <functional>
#include <thread>
#include <mutex>
#include <future>
#include <unistd.h>
using namespace std;
class Foo {
public:
Foo() {}
~Foo() { cout << "foo dtor" << endl; }
void first(function<void()> printFirst) {
printFirst();
}
void second(function<void()> printSecond) {
printSecond();
}
void third(function<void()> printThird) {
printThird();
}
};
int main() {
Foo foo;
thread t1([&foo] {
function<void()> print11 = [] { cout << "1" << endl; };
foo.first(print11);
});
thread t2([&foo] {
function<void()> print21 = [] { cout << "2" << endl; };
foo.second(print21);
});
thread t3([&foo] {
function<void()> print31 = [] { cout << "3" << endl; };
foo.third(print31);
});
sleep(2);
// t1.join();
// t2.join();
// t3.join();
return 0;
}
And I'm getting the error
"Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
If I uncomment the three join() lines, the program exit normally.
I have a feeling that the error is due to use after free, but cannot explain why. What I'm thinking is the main thread will sleep 2 seconds before it really finishes, and during the main thread is sleeping, the t1, t2, t3 should already finish. Hence, even if foo is destroyed, the three thread won't use it after 2 seconds. As far as I understand, it should not have use after free problem. Could anybody explain? Thanks!
This does not look to me like a use after free problem, and it's not a race condition either. It's required behavior. Attempting to destroy a thread object that is in a joinable state (which yours would be under the circumstances) is required to terminate the program (N4835, §[thread.thread.destr]/1):
~thread();
If joinable(), calls terminate(). Otherwise, has no effects. [Note: Either implicitly detaching or
joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach)
or performance (for join) bugs encountered only when an exception is thrown. Thus the programmer
must ensure that the destructor is never executed while the thread is still joinable. —end note]
A thread is joinable() from the time it starts to run until the time it is join()ed or detach()ed.
Summary
Destroying a thread must abort the program if the thread is in a joinable state. To avoid this, join() the thread(s) before destroying them.
The operating system is under no obligation to run your other threads when you sleep(2). It could let Google Chrome have that time slice, or it could use it to do its own background tasks, or it could just sit there on its thumbs.
That logic you just went through of "This thread should only last two seconds at most, so sleeping will do it" is called a race condition. You've got two threads and you're making big assumptions about what order things in those threads will happen, without actually enforcing those assumptions. Effectively, your threads enter into a race: if the three child threads win the race, then your program works fine, but if the main thread wins the race, then your program exhibits undefined behavior. And if your program has a chance of exhibiting undefined behavior, then that means that your program's behavior is undefined.
By adding the join calls, you enforce your assumption. You demand that the main thread cannot exit until the other three threads finish, which is what you were implicitly assuming before. This makes your program's behavior defined.

Code crashes when creating new thread c++

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.

c++ std::thread: Is this code guaranteed to deadlock?

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.

What's the proper way of implementing 'sleeping' technique using C++?

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.

Proper way to terminate a thread in c++

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.