9

I create a thread in a class member method like this:

void MyClass::startThread()
{
    T.reset( new std::thread( &MyClass::myThreadMethod, this ) );
}

void MyClass::myThreadMethod()
{
    // ...
}

where

// In header file
std::unique_ptr<std::thread> T;

When I run MyClass::startThread(), I receive this:

Signal received: SIGABRT (Aborted) ...

If I step the code, it happens in the thread constructor.

I tried to removed the unique_ptr like this:

void MyClass::startThread()
{
    std::thread* T = new std::thread( &MyClass::myThreadMethod, this );
}

and the same thing occurred. I use gcc 4.8.2 on NetBeans 7.4 on Linux/Kubuntu 12.04.

Someone knows what happens?

Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
dom_beau
  • 2,437
  • 3
  • 30
  • 59

2 Answers2

17

This happens when an std::thread is destroyed without a prior call to std::thread::detach() or std::thread::join(). You should call either of the two, and what to call depends on your desired behavior.

void MyClass::startThread() {
    T.reset( new std::thread( &MyClass::myThreadMethod, this ) );
    T->join();  // Wait for thread to finish
}

or

void MyClass::startThread() {
    T.reset( new std::thread( &MyClass::myThreadMethod, this ) );
    T->detach();  // Leave thread on its own (do not wait for it to finish)
}

As a side note, you can remove your use of std::unique_ptr by making the std::thread itself a member:

class MyClass {
    std::thread t;
};

To assign t a thread, you can construct one and move assign it to t:

t = std::thread(&MyClass::myThreadMethod, this);
Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
  • Hello Mark Garcia, 1) removing the unique_ptr is correct, I should have though to it before. 2) I believe it doesn't worth to start a thread if we call join() right after in the same function??? 3) even with a detach, the signal is raised in the *constructor*. – dom_beau Feb 07 '14 at 05:25
  • 2
    @dom_beau I've made a [test](http://coliru.stacked-crooked.com/a/839988ed13bedebf) showing that the problem is solved with the use of either detach or join. For (2), of course, join is usually called for long-running actions and thus calling it immediately would make execution effectively synchronous. The above is only for demonstration. (3) You may be assigning another thread to your `std::thread`, and doing that would destroy the previous object (e.g. calling `.reset` on the `unique_ptr` that already contains an `std::thread`). – Mark Garcia Feb 07 '14 at 05:32
  • The test you made of course must work. But my code looks like yours. I will try to build your code as a spike solution to test it as soon as I will have my computer. But I must tell you that my code is mostly like yours and the SIGABRT is raised in the *constructor* of the thread, that is, before it can reach the `join()` or the `detach()`. – dom_beau Feb 07 '14 at 12:20
  • ...by the way, I don't have this strange behaviour when I use a static member. But in that case, I must use a "communication" structure to pass data pointers between the thread and the current object because the static member cannot access non-static data... – dom_beau Feb 07 '14 at 12:23
5

According to Mark Garcia suggestion and example, and according to this question I just added -pthread as option to the compiler.

For an unknown reason, my other projects work correctly but I believe that it is due to Boost or Open CV that must include something that was missing from this current test.

Anyway, for the moment, it works.

Thanks!

Community
  • 1
  • 1
dom_beau
  • 2,437
  • 3
  • 30
  • 59