I'm trying to understand C++ memory management. As far as I know, objects on stack are guaranted to live (if stack is now overflown) only in current block of code. If I call a function from this block and pass a link of a stack object to this function it must work because calling block is still alive.
What happens with stack objects if I start a new thread from current block of code? As far as I understand this block is considered as finished.
The problem is that stack variables live some time after block finishes so I can't understand if they are guaranted to live or not.
Here I have some code. It compiles and works well but I suppose that it is not guaranted to work.
main.h:
#include <QObject>
#include <QThread>
#ifndef MAIN_H
#define MAIN_H
class MyThread : public QThread
{
Q_OBJECT
virtual void run();
signals:
void returnVar(int *aPtr, int *bPtr);
public:
int *a;
int *b;
};
class MyClass : public QObject
{
Q_OBJECT
int a; // Is it considered stack or global?
void someFunc(int *aPtr, int *bPtr);
MyThread thread; // Is it OK to create thread objects like this or should I use heap only?
public:
MyClass();
public slots:
void varAdded(int *aPtr, int *bPtr);
};
#endif // MAIN_H
.cpp file:
#include <QCoreApplication>
#include <QDebug>
#include "main.h"
void MyThread::run()
{
qDebug() << "A in thread: " << *a << ", B in thread: " << *b;
emit returnVar(a, b);
}
MyClass::MyClass()
{
a = 1;
int b = 2;
someFunc(&a, &b);
//MyThread thread; // If i declare thread here program will crush because thread was destroyed while running
QObject::connect(&thread, SIGNAL(returnVar(int*, int*)), this, SLOT(varAdded(int*, int*)));
thread.a = &a;
thread.b = &b;
// Is current block considered alive when I start a thread?
// As far as I understand it it not alive any more. Am I right?
thread.start();
// If I give this block some time I can create stack thread object in constructor and it will work
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
void MyClass::someFunc(int *aPtr, int *bPtr)
{
// As far as I understand these objects will work fine anyway because calling block is alive.
// Am I right?
qDebug() << "A: " << *aPtr << ", B: " << *bPtr;
}
void MyClass::varAdded(int *aPtr, int *bPtr)
{
qDebug() << "A returned from thread: " << *aPtr << ", B returned from thread: " << *bPtr;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyClass myClass;
return a.exec();
}
My questins are:
Are a and thread stack or global objects?
Is it OK to declare thread objects as I did or should I create them only in heap?
Are a and b objects guaranted to live in thread?
Are a and b objects guaranted to live when they (their references) return from thread?
I appreciate any help.
Your MyClass has 2 instance variables: int a and MyThread thread. Lifetime of these is bound to MyClass'es lifetime. Hence, since you declare MyClass on stack in main function these two variables will live in the same scope.
Now, in MyClass'es constructor you initialize fields of MyThread with pointer to variable a which, as already shown, is a stack variable alive throughout the whole program runtime, and a local variable int b which will cease to exist (hence the pointer will be invalid and dereferencing it is an undefined behaviour) as soon as the constructor finishes running.
So:
a and thread are stack variables, but since their parent (MyClass instance) is declared in main scope of main function they will be valid for the whole duration of the program
I would say so, but I'm in no way Qt expert (quick search around the net suggests it's safe to declare Qt objects on stack as long as you know their lifetime).
No, b will go out of scope hence dereferencing pointer to it results in UB. Your program may work, but it's unsafe to do so.
What Qt guarantees is that what you pass as arguments to a signal is delivered to signal's receiver. From what I gathered by reading this article Qt will copy the arguments (so, if the arguments are classes they will be copy constructed) and dispatch the call to appropriate thread (if subscription was done from different thread than the one emiting the signal). This however does not prolong (or in any other way control) the lifetime of objects pointed to via your pointer - one should use shared_ptr<T> if you want guarantee that the object is delivered intact.
Related
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).
}
I am finding it very strange. Please, help me to explain this. I have a class which starts infinite loop in a separate thread, and two classes which inherit it. One of the classes implements the interface to be triggered outside as std::shared_ptr, and another one class hold this interface as std::weak_ptr. Please look at the code below. Sorry for a lot of code, I was trying to be as short as it possible to reproduce the error. Why sometimes have I pure virtual call in Sender::notify function? As far as I know std::shared_ptr is reentrant.
#include <iostream>
#include <memory>
#include <thread>
#include <atomic>
#include <list>
#include <mutex>
class Thread : private std::thread {
std::atomic_bool run {true};
public:
Thread() : std::thread([this](){ thread_fun(); }) {}
void thread_fun() {
while (run) loop_iteration();
}
virtual void loop_iteration() = 0;
virtual ~Thread() {
run.exchange(false);
join();
std::cout << "Thread released." << std::endl;
}
};
class Sender : public Thread {
public:
class Signal{
public:
virtual void send() = 0;
virtual ~Signal(){}
};
void add_receiver(std::weak_ptr<Signal> receiver) {
std::lock_guard<std::mutex> lock(receivers_mutex);
receivers.push_back(receiver);
}
void notify() {
std::lock_guard<std::mutex> lock(receivers_mutex);
for (auto r : receivers)
if (auto shp = r.lock())
shp->send(); //Somethimes I get the pure virtual call here
}
private:
std::mutex receivers_mutex;
std::list<std::weak_ptr<Signal>> receivers;
void loop_iteration() override {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
notify();
}
};
class Receiver : public Thread, public Sender::Signal {
std::atomic_bool notified {false};
public:
void send() override {
notified.exchange(true);
}
private:
void loop_iteration() override {
std::this_thread::sleep_for(std::chrono::milliseconds(250));
std::cout << "This thread was " << (notified? " " : "not ") << "notified" << std::endl;
}
};
int main() {
std::shared_ptr<Thread>
receiver = std::make_shared<Receiver>(),
notifier = std::make_shared<Sender>();
std::dynamic_pointer_cast<Sender>(notifier)->add_receiver(
std::dynamic_pointer_cast<Sender::Signal>(receiver));
receiver.reset();
notifier.reset();
return 0;
}
Polymorphism doesn't work as you may expect during construction and destruction. The current type is the most derived type that still exists. When you are in Thread::~Thread the Sender part of your object has already been completely destroyed so it wouldn't be safe to call its overrides.
When thread_fun tries to run loop_iterator() before the constructor finishes or after the destructor starts, it will not polymorphically dispatch, but instead it will call Thread::loop_iteration which is a pure virtual function (= 0).
See https://en.cppreference.com/w/cpp/language/virtual#During_construction_and_destruction
Here is a demonstration of this : https://godbolt.org/z/4vsPGYq97
The derived object is destroyed after one second, at which point you see the output change indicating that the virtual function being called changes at that point.
I'm not sure if this code is valid, or if destroying the derived part of the object while one of its member function is being executed is Undefined Behavior.
In addition to what François Andrieux noted, your real problem is that you are starting the thread running, using this object, before its construction is finished. It may or may not see the derived type constructed yet, depending on timing.
It's not calling thread_fun from the constructor, as he implies. It's calling that on a different thread, at some unknown point in the future. It might happen on a different core before this base class constructor has returned, or at any other random point during the derived class's construction process, or much later.
You can't safely start the thread's function until the object is ready to be used.
Separate creation from making it go. That's the easiest thing.
meanwhile
virtual ~Signal(){}
Don't define empty destructors. Write =default instead.
But, use override in the derived class, and don't use virtual there.
You have a problem in that you assume that the spawned thread does not start immediately and the current thread has time to initialize the state of the current object before it does anything.
This does not hold which causes two issues.
You accesses state in the current object that has not been initialized.
You use a polymorphic function that is not guranteed to work until after the object is fully constructed.
You make a slight assumption in your destructor:
You inherit from an object that does not have a virtual destructor.
Your thread may still accesses state after the object has started its destruction. If it does (access destroyed) then it is UB. Your thread needs to be able to check if the current object state is valid (i.e. All derived classes must get a lock on run and make sure its state is till true and all destructors must set run to false.
Your problem lies here:
class Thread : private std::thread {
std::atomic_bool run {true};
public:
Thread()
// Here you are starting a separate thread of execution
// That calls the method thread_fun on the current object.
//
// No problem so far. BUT you should note that "this" object
// is not fully constructed at this point and there is no
// guarantees that the thread you just started will wait
// for this thread to finish before doing anything.
: std::thread([this](){ thread_fun(); })
{}
void thread_fun() {
// The new thread has just started to run.
// And is now accessing the variable `run`.
//
// But `run` is a member and initialized after
// the base class so you have no idea if the parent
// thread has correctly initialized this variable yet.
//
// There is no guratnee that the parent will get to
// the initialization point of `run` before this new thread
// gets to this point where it is using it.
while (run) {
// Here you are calling a virtual function.
// The trouble is that virtual functions are not
// guranteed to work as you would expect until all the
// constructors of the object have run.
// i.e. from base all the way to most derived.
//
// So you not only have to wait for this base class to
// be full constructed you must wait until the object
// is full constructed before you call this method.
loop_iteration();
}
}
virtual void loop_iteration() = 0;
virtual ~Thread() {
// You have a problem in that std::thread destructor
// is not virtual so you will not always call its destructor
// correctly.
//
// But lets assume it was called correctly.
// When you get to this point you have destroyed the
// the state of all derived parts of your object.
// So the function your thread is running better
// not touch any of that state as it is not all invalid
// and doing so is UB.
//
// If your object had no state then you are fine.
run.exchange(false);
join();
std::cout << "Thread released." << std::endl;
}
};
I think a better solution is to make the std::thread a member of your object, and force any threads to hold until you have the state correctly initialized (at the point where you create the object).
class Thread {
std::atomic_bool run;
std::thread thread;
public:
Thread(std::function<void>& hold)
// Make sure run is initialized before the thread.
: run{false}
, thread([this, &hold](){ thread_fun(hold); })
{}
void thread_fun(std::function<void>& hold) {
// Pass in a hold function.
// The creator of your objects defines this
// It is supposed to make objects created until you
// have all the state correctly set up.
// once it is you allow any threads that have called
// hold to be released so they can execute.
hold();
while (run) loop_iteration();
}
virtual void loop_iteration() = 0;
virtual ~Thread() {
run.exchange(false);
join();
std::cout << "Thread released." << std::endl;
}
};
Then you can create a simple barrier to use in hold:
class Barrier
{
bool threadsShouldWait = true;
std::conditional_variable cond;
std::mutex mutex;
void wait() {
std::unique_lock<std::mutex> lock(mutex);
cond.wait([&](){return !threadsShouldWait;}, lock);
}
void release() {
std::unique_lock<std::mutex> lock(mutex);
threadsShouldWait = false;
cond.notify_all();
}
}
int main()
{
// Note you don't need to use the same barrier for
// both these variables. I am just illustrating one use case.
Barrier barrier;
std::shared_ptr<Thread> receiver = std::make_shared<Receiver>([&barrier](){barrier.wait();});
std::shared_ptr<Thread> notifier = std::make_shared<Sender>([&barrier](){barrier.wait();});
barrier.release();
Is it possible to declare a unique_ptr inside a class (nullptr), then pass its raw value (with get()) to a function which create the instance it will point to?
I have to run an application with a Qt made interface. Qt needs the Qapplication to start in the same thread in which the UI will be updated. To do so, since I cannot do that into my main because i'm also using QP framework(which has a blocking function similar to the qt exec()), i created a class that contais 2 unique_ptr:
//MyClass.h
std::unique_ptr<Qapplication> Core;
std::unique_ptr<MainWindow> UI;
then in my code inside the constructor of MyClass i start the thread:
std::thread(&MyClass::threadfunc,this, UI.get(), Core.get());
the thread is:
int MyClass::threadfunc(MainWindow* UI,Qapplication* Core){
int dummy=0;
Core = new QApplication(dummy,nullptr);
UI= new MainWindows();
UI->show;
return Core ->exec();
}
I need the pointer in MyClass since I need to update the UI, so with the pointer to mainwindows I should be able to call its methods, but since it has to be created after QApplication, i cannot istance it in my class constructor.
Then I decided to create all in the separated thread, and since I can guarantee that the pointer in my class will be destroyed after Qt is stopped, I read that it is possible to declare the pointer as unique ones (I could just use the shared pointer, but I want to understand if it is possible to use unique pointers).
To create unique poiters i need make_unique function, but since i passed the raw pointers I cannot use that. I cannot even pass the pointer since they have to be unique (and I use them in MyClass)
The question is, is there a better solution to implement what i want to obtain? or can I obtain it with the implementation I'm using just by doing something different?
thanks
Your code is so messy it is impossible to fix it.
Looks like you are using Qt, so only proper use of QApplication looks like this:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
return app.exec();
}
You do not have need or skill do do anything else with it.
The only exception from this pattern is described in documentation when application have no UI mode.
Do no use threads. I know they are fashionable now, and this is a buzz word, but they are very hard to master (muti threading bugs are extremly hard to fix and understand and it is easy to write code which will work on 90% computers and will fail always on 10% of machines), so this feature should be avoided by beginners as long as possible.
First master basics of developing Qt applications without threads of any kind.
Is it possible to declare a unique_ptr inside a class (nullptr), then pass its raw value (with get()) to a function which create the instance it will point to?
You can, but the way you're going about this (from the limited code snipped you've posted) sounds convoluted. Why does threadfunc need to take in raw pointers? Can't it take unique pointers? Seems it can, since you control MyClass.
At any rate, maybe something like this will accomplish what you want. We're basically stuffing the raw pointer inside threadfunc into the class's unique ptr.
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
struct A {
std::unique_ptr<int> p;
std::thread t1;
A() {
p = nullptr; //happens by default, but explicit for OP
}
void start()
{
//int *rawp_;
t1 = std::thread(&A::threadfunc, this, p.get());
//p = std::unique_ptr<int>{rawp_};
}
void threadfunc(int* rawp){
rawp = new int(5);
p = std::unique_ptr<int>{rawp};
std::cout << "A::p " << *(p) << std::endl;
std::cout << "Sleeping for 5 seconds" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * (*rawp)));
}
void end()
{
t1.join();
}
};
int main()
{
A a;
// std::cout << *(a.p) << std::endl; //--> SEGFAULT
a.start();
a.end();
}
I am currently learning multithreading in c++11 and I am confused with the way to terminate a thread safely.
In c++, I know the way to create threads and use thread.join() to safely ensure main() to wait for all threads to finish before quitting itself.
However, I found that some multithread codes implemented via pointers are able to run even without using thread.join().
class Greating
{
public:
Greating(const int& _i):i_(_i){}
~Greating(){}
int i_;
void say()
{
std::cout << "Hello World" << i_ << std::endl;
}
};
int main(){
Greating greating1(1);
Greating greating2(2);
std::thread t1(&Greating::say, greating1);
std::thread t2(&Greating::say, greating2);
return 0;
}
The code shown above will absolutely report the error "terminate called without an active exception
Aborted (core dumped)", because I did not use t1.join() and t2.join().
However, I found in some codes when they use the pointer to manage the thread, this does not become a problem, as shown below.
class Greating
{
public:
Greating(const int& _i):i_(_i){}
~Greating(){}
int i_;
void say()
{
std::cout << "Hello World" << i_ << std::endl;
}
};
int main(){
Greating greating1(1);
Greating greating2(2);
std::thread* tt1 = new std::thread(&Greating::say, greating1);
std::thread* tt2 = new std::thread(&Greating::say, greating2);
return 0;
}
The output is:
Hello WorldHello World12
Hello World12
There is no error reported. This made me very confused.
So my question is:
Why when we use pointer to manage the thread, we could not use the function thread.join()?
How to correctly terminate a thread? (probably wait for the callable function to finish?)
Thanks very much!
When creating objects with dynamic allocation, you have to deallocate the memory with operator delete so it calls appropriate destructor.
In the first example, two std::thread objects are created. At the end of main function, the destructor std::thread::~thread is called. Since the threads are not joined, the destructor reports an error.
On the other hand, in the second example, you called operator new so you create objects with dynamic allocation. But, you didn't call operator delete, so the destructor is not called. That is, the program didn't check whether the threads are joined.
Therefore, the only way to correctly terminate a thread is to call std::thread::join. If you want to use pointers, you have to do as following:
std::thread *th = new std::thread(foo);
...
th->join();
delete th;
I have a question concerning this code which I want to run on QNX:
class ConcreteThread : public Thread
{
public:
ConcreteThread(int test)
{
testNumber = test;
}
void *start_routine()
{
for(int i = 0; i < 10; i++)
{
sleep(1);
cout << testNumber << endl;
}
}
private:
int testNumber;
};
class Thread
{
public:
Thread(){};
int Create()
{
pthread_t m_id;
return pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this);
}
protected:
virtual void *start_routine() = 0;
private:
static void *start_routine_trampoline(void *p)
{
Thread *pThis = (Thread *)p;
return pThis->start_routine();
}
};
Now, when I run this code without the sleep in *start_routine, it will simply print the number 10 times, before continuing on to the next line of code (sequential instead of parallel). However, when I use a sleep like in the code, it doesn't print any numbers at all and simply goes on to the next line of code. Why doesn't sleep work and how can I make a thread like this work, instead of running sequential?
Note 1: If you only have 1 processor the code can only be done sequentially no matter how many threads you create. Each thread is given a slice of processor time before it is swapped out for the next threads.
Note 2: If the main thread exits pthreads will kill all child threads before they have a chance to execute.
Now to answer you questions:
Without the sleep. The thread once started has enough time in the single slice it was given to execute the loop 10 times completely.
With the sleep: Your worker thread is going to sleep for a full second. So your main thread has time to do a lot of work. If the main thread exits in this time the worker will be killed.
I would make the following changes:
// Remove the Create() method
// Put thread creation in the constructor.
// Make the thread variable part of the object
pthread_t m_id;
Thread()
{
if (pthread_create(&m_id, NULL, &(this->start_routine_trampoline), this) != 0)
{
throw std::runtime_error("Thread was not created");
}
}
// Make sure the destructor waits for the thread to exit.
~Thread()
{
pthread_join(m_id);
}
If you go and look at boost threading library. you will find that all the little mistakes like this have already been taken care of; Thus making threading easier to use.
Also note. That using a static may work but it is non portable. This is because pthread's is a C library and is thus expecting a function pointer with a C ABI. You are just getting lucky for your platform here. You need to define this as a function and declare the ABI by using extern "C"
// This needs to be a standard function with C Interface.
extern "C" void *start_routine_trampoline(void *p)
{
}
Try to make the pthread_t id a class member instead of a function local variable. That way the caller can pthread_join it.
Not doing this is technically a resource leak (unless the thread is specifically not joinable). And joining will avoid the issue that Martin York described.
From man pthread_join:
The joined thread th must be in the joinable state: it must not have
been detached using pthread_detach(3) or the PTHREAD_CREATE_DETACHED
attribute to pthread_create(3).
When a joinable thread terminates, its memory resources (thread
descriptor and stack) are not deallocated until another thread performs
pthread_join on it. Therefore, pthread_join must be called once for
each joinable thread created to avoid memory leaks.
Going off on a tangent here... With respect to Martin York's post:
Also note. That using a static may work but it is non portable. This is because pthread's is a C library and is thus expecting a function pointer with a C ABI. You are just getting lucky for your platform here. You need to define this as a function and declare the ABI by using extern "C" // This needs to be a standard function with C Interface. extern "C" void * start_routine_trampoline(void * p) {...}
I'm not so sure about that...
(1) C++ was designed to be as compatible with C as possible. There are a few differences... But I was under the impression that extern "C" was used mostly to circumvent the name-mangling required to implement C++ function overloading.
(2) It seems like, once you have the function pointer, the calling conventions (what gets pushed on the stack to make the function call) just has to be the same between C & C++. Otherwise, how would function pointers work?
E.g.:
C code:
void bar( int i ) { printf( "bar %d\n", i ); }
C++ code:
class Foo
{
public:
static void foo( int i ) { cout << "foo " << i << endl; }
};
extern "C" { void bar(int); }
int main()
{
void (*p)(int);
p = & Foo::foo;
(*p)(1);
p = & bar;
(*p)(2);
}