Proper way to pass same pointer to 2 threads(each thread runs another operation) - c++

What is the proper way to pass a pointer to 2 threads that each one of the threads runs another operation?
#include <chrono>
#include <iostream>
#include <vector>
#include <thread>
#include <random>
struct Unit {
Unit(uint64_t id_) :
id(id_),
v(1000000000)
{}
uint64_t id;
std::vector<int> v;
};
void operation1(Unit* unit) {
std::cout << "Hello operation1";
}
void operation2(Unit* unit) {
std::cout << "Hello operation2";
}
void operationMain() {
Unit* unit = new Unit(1);
std::thread at1(&operation1, unit);
std::thread at2(&operation2, unit);
at1.detach();
at2.detach();
}
int main123(int argc, char** argv)
{
std::thread t(&operationMain);
t.join();
return 0;
}
Here is my code, and I think I have a memory leak because 'unit' is passing to several operations in different threads.
Any suggestions?

My suggestion is to not use detach() but use join() or not share the object or create one of in (say) the at1 thread, detach() it and create at2 the as a thread within that second thread and join in the at1 thread or allocated a shared_ptr<> but shared ownership is way down the list as 'avoid where possible'.
detach() means a thread executes independently and you cannot call join() on a detached thread so you have no suitable point at which to cause the delete of the dynamically allocated Unit to take place in the calling thread.
It's not clear from the question why you've allocated shared resources and then called detach().
On my machine I get no output (even with a realistic size for the vector) because the main() thread ends before the detach threads do anything meaningful.
This should work fine:
void operationMain() {
std::unique_ptr<Unit> unit (std::make_unique<Unit>(1));
std::thread at1(operation1, unit.get());
std::thread at2(operation2, unit.get());
at1.join();
at2.join();
//at1 and at2 have terminated and the unique_ptr destructor will delete the object (RAII).
}

Related

Correct way to start a function object thread in C++?

I have this code so far :
#include <iostream>
#include <string>
#include <windows.h>
#include <iomanip>
#include <thread>
#include <chrono>
#include <atomic>
class test {
public:
thread t1;
test() : t1(&test::work, this) {
}
void work() {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
};
int main()
{
test t;
while (true) {
cout << "in main" << endl;
Sleep(1000);
}
return 0;
}
Question 1: Is this how I'm suppose to create a thread in a class object for one function only after I initialize the object?
Question 2: I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Question 3: do I need to delete or join the thread or do any kind of memory management?
Problem How can I create the thread somewhere else in the function of the objects other than the constructor? I have did this and it didn't work
void work() : t1(&test::work, this) {
while (true) {
cout << "in thread";
Sleep(1000);
}
}
Is this how I'm supposed to create a thread in a class object for one function only after I initialize the object?
It's one option. Another is t1([this]{ work(); }).
Relevant question: Start thread with member function
Be aware that, generally, the current instance (*this) may not be fully constructed when the thread starts executing.
I've seen people write atomic_bool and run(), is that necessary? and what is it for?
Don't know what run() is, but atomic variables are used for communication between threads via shared memory.
Do I need to delete or join the thread or do any kind of memory management?
No, you don't need any of these since your program never ends (at least normally).
How can I create the thread somewhere else in the function of the objects other than the constructor?
You can assign the thread member variable t1 a new value.
I would suggest reading some good book to learn such basics.

Why can detached thread in C++11 execute even if the destructor has been called

I just read the doc about std::thread.detach() in C++11.
Here is my test:
#include <iostream>
#include <thread>
#include <chrono>
static int counter = 0;
void func()
{
while (true) {
std::cout<<"running..."<<std::endl;
std::cout<<counter++<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main()
{
{
std::thread t(func);
t.detach();
} // t is released after this line
// t has died, so who is holding the resources of the detached thread???
std::cin.get();
return 0;
}
This code works as expected. So it seems that the thread can keep running even if its destructor has been invoked. Is this true?
If it's true, who on earth holds the resources of the thread after the object t is released? Is there some mechanism to hold the resources, for example, a hidden anonymous object?
In C++, std::thread does not manage the thread of execution itself. C++ does not have controls for managing the thread of execution at all.
std::thread manages the thread handle - the identifier of a thread (thread_t in Posix world, which was largely a model for std::thread). Such identifier is used to communicate (as in control) with the thread, but in C++, the only standard way of communication would be to join the thread (which is simply waiting for thread's completion) or detaching from it.
When std::thread destructor is called, the thread handle is also destructed, and no further controlling of the thread is possible. But the thread of execution itself remains and continues being managed by implementation (or, more precisely, operation system).
Please note, for non-detached threads std::threads destructors throws an exception if the thread has not been joined. This is simply a safeguard against developers accidentally loosing the thread handle when they didn't intend to.
You are correct that the thread keeps running if detached after the thread's destructor.
No one on earth hold the resources (unless you make arrangements for someone to). However when your application exits, the application shutdown process will end the thread.
One can still arrange to communicate with and "wait" for a detached thread. In essence, join() is a convenience API so that you don't have to do something like this:
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
static int counter = 0;
std::atomic<bool> time_to_quit{false};
std::atomic<bool> has_quit{false};
void func()
{
while (!time_to_quit) {
std::cout<<"running..."<<std::endl;
std::cout<<counter++<<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
has_quit = true;
}
int main()
{
{
std::thread t(func);
t.detach();
} // t is released after this line
using namespace std::chrono_literals;
std::this_thread::sleep_for(3s);
time_to_quit = true;
while (!has_quit)
;
std::cout << "orderly shutdown\n";
}
Threads of executions exist independently from the thread objects that you use to manage them in C++. When you detach a thread object, the thread of execution continues running, but the implementation (usually in combination with the Operating System) is responsible for it.

When std::thread is destructed and what happen to the shared_ptr if the pointer point to it?

When I create a std::thread instance, when will it be destructed? Is the time when the thread finish its task then it is destructed or it works as a normal object which will be destructed when it will not be used anymore?
//a fake function for std::thread
void func();
void main()
{
auto threadPtr = std::make_shared<std::thread>(func)
threadPtr->join();
// is thread object which threadPtr point destructed in here ?
//... other stuffs ....
}
Is thread object destructed after threadPtr->join()?
Is thread object destructed after threadPtr->join()?
No. join() ends the thread of execution that the std::thread object represents, it does not destroy the std::thread object.
When I create a std::thread instance, when will it be destructed?
It will be destroyed when threadPtr goes out of scope since it is an automatic object(it has automatic storage duration). The std::shared_ptr destructor will call the std::thread destructor, and then it will free the memory it obtained.
The underlying operating system thread may have terminated but that isn't the same as the C++ std::thread object being destructed.
Execute the following:
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
std::mutex cout_mutex;
std::atomic<bool> waiter{true};
void func(){
{
std::lock_guard<std::mutex> guard(cout_mutex);
std::cout << "funky\n";
}
while(waiter);//cheap spin waiting...
}
int main() {
auto threadPtr = std::make_shared<std::thread>(func);
{
std::lock_guard<std::mutex> guard(cout_mutex);
std::cout << "an active thread id: "<<threadPtr->get_id()<<'\n';
}
waiter=false;
threadPtr->join();
std::cout << "terminated thread id: "<< threadPtr->get_id()<<'\n';
return 0;
}
The output varies but possible output here is:
an active thread id: 47441922455296
funky
terminated thread id: thread::id of a non-executing thread
The object contained in threadptr remains valid until destructed but may be referencing a terminated thread.
std::thread is typically an implementation of a wrapper class (or the proxy design pattern). It contains a (possibly empty) reference to what is normally an operating system thread object. When the wrapped thread ends the reference may be made empty.

Creating a class to store threads and calling them

Here is a simplified version of what I am trying to do:
#include <iostream>
#include <vector>
#include <thread>
#include <atomic>
class client {
private:
std::vector<std::thread> threads;
std::atomic<bool> running;
void main() {
while(running) {
std::cout << "main" << std::endl;
}
}
void render() {
while(running) {
std::cout << "render" << std::endl;
}
}
public:
client() {
running = true;
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));
}
~client() {
running = false;
for(auto& th : threads) th.join();
};
};
int main() {
client c;
std::string inputString;
getline(std::cin, inputString);
return 0;
}
(Note: code has been changed since question was written)
What I am trying to do is create a class that holds threads for the main loop(of the class), rendering, and a couple other things. However I cannot get this simplified version to work. I have tried using mutex to lock and unlock the threads, but didn't seem to help any. I do not know why it is not working, but I suspect that it is a result of the use of this in threads.push_back(std::thread(this->main, this));.
The current structure of the code doesn't have to remain... The only requirement is that uses one of it's own member functions as a thread (and that, that thread is stored in the class). I am not sure if this requires two classes or if my attempt to do it in one class was the correct approach. I have seen many examples of creating an object, and then calling a member that creates threads. I am trying to avoid this and instead create the threads within the constructor.
The problem here is that you do not wait for the threads to end. In main you create c. This then spawns the threads. The next thing to happen is to return which destroys c. When c is destroyed it destroys its members. Now when a thread is destroyed if it has not been joined or detached then std::terminate is called and the program ends
What you need to do is in the destructor, set running to false and then call join on both the threads. This will stop the loop in each thread and allow c to be destructed correctly.
Doing this however brings up another issue. running is not an atomic variable so writing to it while threads are reading it is undefined behavior. We can fin that though by changing running to a std::atomic<bool> which provides synchronization.
I also had to make a change to the thread construction. When you want to use a member function the syntax should be
std::thread(&class_name::function_name, pointer_to_instance_of_class_name, function_parameters)
so in this case it would be
threads.push_back(std::thread(&client::main, this));
threads.push_back(std::thread(&client::render, this));

Why do I need to join a thread even if I use std::future::get?

void
set_string(std::promise<std::string>& p)
{
p.set_value("set from thread");
}
int
main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread t(&set_string, std::ref(p));
std::cout << f.get() << std::endl;
t.join();
}
Why do I need to call t.join() after I call f.get()? I thought that f.get() will block the main thread until it can get the result and that would mean that the thread has already finished.
Because even after thread finishes execution it is still joinable. You can call detach to allow independend execution. In this case you might want to use set_value_at_thread_exit member of promise to lessen chance that main finishes before thread:
#include <iostream>
#include <string>
#include <thread>
#include <future>
void set_string(std::promise<std::string>& p)
{
p.set_value_at_thread_exit("set from thread");
}
int main()
{
std::promise<std::string> p;
std::future<std::string> f = p.get_future();
std::thread(&set_string, std::ref(p)).detach();
std::cout << f.get() << std::endl;
}
http://coliru.stacked-crooked.com/a/1647ffc41e30e5fb
I believe the rationale for threads is simply that you either explicitly join them or that you explicitly detach them, but if a thread object gets destroyed before either happened, you probably have a problem with your design. The decision was not to assume you want to detach it or join it when the destructor is called, because either one is a bad guess in most situations.
Further, concerning your case, it doesn't matter where the future is set from. The requirements for the thread object are not touched by how it triggers the future, they stay the same.
Note that in your case, since you don't care about the thread any longer, you could simply detach it.