例子
#include <stdio.h>
#include <stdlib.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <string>
#include <list>
#include <list>
#include <vector>
#include <chrono>
#include <memory>
#include <mutex>
std::mutex g_display_mutex;
struct Foo {
public:
int n;
std::string s;
Foo() {
std::cout << "Foo" << std::endl;
}
Foo(int i) :n(i) {
std::cout << "Foo(int i)" << i << std::endl;
s = "s=" + std::to_string(i);
}
};
void thread_task(Foo& f, std::string name) {
auto threadid = std::this_thread::get_id();
g_display_mutex.lock();
std::cout << "[thread#" << threadid << name << "]Entry." << std::endl;
g_display_mutex.unlock();
std::this_thread::sleep_for(std::chrono::seconds(2));
{
// http://en.cppreference.com/w/cpp/thread/lock_guard
std::lock_guard<std::mutex> lock(g_display_mutex); // RAII-style
std::cout << "[thread#" << threadid << name << "]: " << f.s << std::endl;
std::cout << "[thread#" << threadid << name << "]Leave." << std::endl;
}
}
void thread_task_with_shared_parameter(std::shared_ptr<Foo> f, std::string name) {
thread_task(*f, name);
}
int main(int argc, const char *argv[])
{
unsigned int n = std::thread::hardware_concurrency();
std::cout << n << " concurrent threads are supported.\n";
std::thread not_a_thread;
{
Foo stack_foo(22);
//http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared
auto shared_foo = std::make_shared<Foo>(66);
std::thread t2(thread_task_with_shared_parameter, shared_foo, "shared parameter");
{
std::lock_guard<std::mutex> lock(g_display_mutex); // RAII-style
std::cout << "underlying thread handle: " << t2.native_handle() << ", joinable: " << t2.joinable() << std::endl;
}
std::thread t3(thread_task, std::ref(stack_foo), "stack parameter");
// http://en.cppreference.com/w/cpp/thread/thread/join
// Blocks the current thread until the thread identified by *this finishes its execution.
//t2.join();
//t3.join(); //stack_foo will be valid in thread_task
// http://en.cppreference.com/w/cpp/thread/thread/detach
// After calling detach *this no longer owns any thread.
// So, it
t2.detach();
t3.detach(); // stack_foo will be invalid in thread_task
{
std::lock_guard<std::mutex> lock(g_display_mutex); // RAII-style
std::cout << "std::thread created with shared parameter is" << (t2.joinable()? "" : " not ") << "joinable" << std::endl;
std::cout << "std::thread created with stack parameter is" << (t3.joinable() ? "" : " not ") << "joinable" << std::endl;
}
/*
// VS 2015
~thread() _NOEXCEPT
{ // clean up
if (joinable())
_XSTD terminate();
}
*/
}
g_display_mutex.lock();
std::cout << "All threads should ~thread()." << std::endl;
g_display_mutex.unlock();
std::vector<std::string> myvector = { "10", "20","30" };
myvector.emplace_back("100");
myvector.emplace_back("200");
std::cout << "myvector contains:";
for (auto& x : myvector)
std::cout << ' ' << x.c_str();
std::cout << '\n';
getchar();
return EXIT_SUCCESS;
}
上面
t2.detach(); t3.detach();
outputted [thread#9912stack parameter]:
2 concurrent threads are supported.
Foo(int i)22
Foo(int i)66
underlying thread handle: 00000048, joinable: 1
[thread#9492shared parameter]Entry.
std::thread created with shared parameter is not joinable
std::thread created with stack parameter is not joinable
All threads should ~thread().
myvector contains: 10 20 30 100 200
[thread#9912stack parameter]Entry.
[thread#9492shared parameter]: s=66
[thread#9492shared parameter]Leave.
[thread#9912stack parameter]:
[thread#9912stack parameter]Leave.
t2.join(); t3.join();
outputted [thread#6676stack parameter]: s=22
2 concurrent threads are supported.
Foo(int i)22
Foo(int i)66
underlying thread handle: 00000048, joinable: 1
[thread#6004shared parameter]Entry.
[thread#6676stack parameter]Entry.
[thread#6004shared parameter]: s=66
[thread#6004shared parameter]Leave.
[thread#6676stack parameter]: s=22
[thread#6676stack parameter]Leave.
std::thread created with shared parameter is not joinable
std::thread created with stack parameter is not joinable
All threads should ~thread().
myvector contains: 10 20 30 100 200
问题:应避免访问脱离作用域的变量 原因:脱离作用域这里指主要只传递生命周期短的变量(如栈上变量)的引用或地址给周期长的线程使用。
这里也有一篇文章C++11 Multithreading – Part 3: Carefully Pass Arguments to Threads