lulyon
lulyon

Reputation: 7235

can not understand std::thread usage

I am reading documents about c++11 multi-threads, and met this example for std::thread.

Code:

void thread_task(int n) {
  ...
}

int main(int argc, const char *argv[])
{
    std::thread threads[5];
    for (int i = 0; i < 5; i++) {
        threads[i] = std::thread(thread_task, i + 1);
    }

    return 0;
}

I do not understand threads[i] = std::thread(thread_task, i + 1);. Is the std::thread a static function call, and returns a reference for std::thread object? Sounds inconceivable, but seems to be what the code say.

Because I would write it like this:

std::thread *threads[5];
for (int i = 0; i < 5; i++) {
    threads[i] = new std::thread(thread_task, i + 1);
}

Thanks.

Upvotes: 1

Views: 223

Answers (4)

Yuushi
Yuushi

Reputation: 26050

Let's go through exactly what is happening:

std::thread threads[5];

This creates an array of 5 std::thread objects, which are default constructed. Currently they represent "not a thread" as this is the state default construction leaves them in.

for (int i = 0; i < 5; i++) {
    threads[i] = std::thread(thread_task, i + 1);
}

This uses the move form of operator=. Because threads are not copyable, only moveable, thread& operator=(thread&& t) is defined while thread& operator=(const thread& t) is not. This assigns the thread object in threads[i] to the newly constructed std::thread(thread_task, i + 1);.

There is no reason to use an array of pointers here. It adds nothing but the possibility for memory leaks.

Upvotes: 13

This:

std::thread(thread_task, i + 1)

is a call to the std::thread constructor, which creates a new thread object and passes it a pointer to the thread_task function, which itself is called with i+1 as parameter.

The assignment is a move assignment (because the right hand side refers to an anonymous object), not a copy assignment. Note that the std::thread copy constructor and copy assignment operator are deleted.

This is actually a cleaner way than using pointers, because the std::thread objects will be destructed automatically when the threads array goes out of scope.

Upvotes: 2

Daniel Frey
Daniel Frey

Reputation: 56873

The default constructor of std::thread creates an instance that does not represent a thread. The assignment is a move-assignment, since copies are also not allowed. It moves the real instance created by std::thread(thread_task, i + 1); into the array.

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254531

Is the std::thread a static function call, and returns a reference for std::thread object?

No, it's creating a temporary thread object; just as int(42) creates a temporary integer. The assignment moves that into the array, since threads are movable and temporaries can be moved from.

Because I would write it like this:

You're introducing dynamic allocation, an extra level of indirection, and memory leaks (unless you also add code to delete them when you're finished) for no good reason.

Upvotes: 2

Related Questions