Namespaces
Variants
Views
Actions

std::thread::thread

From cppreference.com
< cpp‎ | thread‎ | thread
Revision as of 19:35, 27 February 2013 by SuperBoi45 (Talk | contribs)

Template:ddcl list begin <tr class="t-dcl-sep"><td></td><td></td><td></td></tr>

<tr class="t-dcl ">

<td >
thread();
</td>

<td > (1) </td> <td > (since C++11) </td> </tr> <tr class="t-dcl-sep"><td></td><td></td><td></td></tr>

<tr class="t-dcl ">

<td >
thread( thread&& other );
</td>

<td > (2) </td> <td > (since C++11) </td> </tr> <tr class="t-dcl-sep"><td></td><td></td><td></td></tr>

<tr class="t-dcl ">

<td >
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
</td>

<td > (3) </td> <td > (since C++11) </td> </tr> <tr class="t-dcl-sep"><td></td><td></td><td></td></tr>

<tr class="t-dcl ">

<td >
thread(const thread&) = delete;
</td>

<td > (4) </td> <td > (since C++11) </td> </tr> Template:ddcl list end

Constructs new thread object.

1) Creates new thread object which does not represent a thread.
2) Move constructor. Constructs the thread object to represent the thread of execution that was represented by other. After this call other no longer represents a thread of execution.
3) Creates new std::thread object and associates it with a thread of execution. First the constructor copies all arguments args... to thread-local storage as if by the function:
template <class T>
typename decay<T>::type decay_copy(T&& v) {
    return std::forward<T>(v);
}
Any exceptions thrown during evaluation and copying of the arguments are thrown in the current thread, not the new thread.
The code that will be run in the new thread is defined as follows. Let's refer to copied_args as t1, t2, ..., tN, where N is sizeof...(copied_args)and copied_args is the result of calling decay_copy as defined above. The following code will be run in the new thread:
  • If f is pointer to a member function of class T, then it is called. The return value is ignored. Effectively, the following code is executed:
  • (t1.*f)(t2, ..., tN) if the type of t1 is either T, reference to T or reference to type derived from T.
  • ((*t1).*f)(t2, ..., tN) otherwise.
  • If N == 1 and f is pointer to a member data object of a class, then it is accessed. The value of the object is ignored. Effectively, the following code is executed:
  • t1.*f if and the type of t1 is either T, reference to T or reference to type derived from T.
  • (*t1).*f otherwise.
  • f is called as a pointer to a non-member function in all other cases. The return value is ignored. Effectively, f(t1, t2, ..., tN) is executed.
4) The copy constructor is deleted; threads are not copyable. No two std::thread objects may represent the same thread of execution.

Contents

Parameters

other - another thread object to construct this thread object with
f - function to execute in the new thread
args... - arguments to pass to the new function

Exceptions

1-2)
noexcept specification:  
noexcept
  
3) std::system_error if the thread could not be started. The exception may represent the error condition std::errc::resource_unavailable_try_again or another implementation-specific error condition.

Notes

The arguments to the thread function are copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref).

Any return value from the function is ignored. If the function throws an exception, std::terminate is called. In order to pass return values or exceptions back to the calling thread, std::promise or std::async may be used.

Example

#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
 
void f1(int n)
{
    for (int i = 0; i < 5; ++i) {
        std::cout << "Thread " << n << " executing\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
 
void f2(int& n)
{
    for (int i = 0; i < 5; ++i) {
        std::cout << "Thread 2 executing\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}
 
int main()
{
    int n = 0;
    std::thread t1; // t1 is not a thread
    std::thread t2(f1, n + 1); // pass by value
    std::thread t3(f2, std::ref(n)); // pass by reference
    std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
    t2.join();
    t4.join();
    std::cout << "Final value of n is " << n << '\n';
}

Possible output:

Thread 1 executing
Thread 2 executing
Thread 1 executing
Thread 2 executing
Thread 1 executing
Thread 2 executing
Thread 1 executing
Thread 2 executing
Thread 1 executing
Thread 2 executing
Final value of n is 5