原 总结 C++11 thread
缘起
从C++11开始提供了线程的支持,终于可以方便的编写跨平台的线程代码了。除了std::thread类,还提供了许多其它便利同步的机制,本篇总结是C++11学习笔记系列的首篇总结。
std::thread
std::thread定义在<thread>
中,提供了方便的创建线程的功能。
类定义
- class thread
- {
- public:
- thread() noexcept;
- thread( thread&& other ) noexcept;
- template< class Function, class... Args >
- explicit thread( Function&& f, Args&&... args );
- thread(const thread&) = delete;
- ~thread();
- thread& operator=( thread&& other ) noexcept;
- bool joinable() const noexcept;
- std::thread::id get_id() const noexcept;
- native_handle_type native_handle();
- void join();
- void detach();
- void swap( thread& other ) noexcept;
- static unsigned int hardware_concurrency() noexcept;
- };
从定义中我们可以得知:
各个成员函数的简单介绍
例子
因为thread类比较简单,我们通过几个例子来学习。
- #include <thread>
- void some_function() {}
- void some_other_function() {}
- int main()
- {
- std::thread t1(some_function);
- std::thread t2 = std::move(t1);
-
- t1 = std::thread(some_other_function);
- std::thread t3;
- t3 = std::move(t2);
-
- t1 = std::move(t3);
- }
- #include <iostream>
- #include <thread>
- #include <chrono>
-
- void foo() {
- std::this_thread::sleep_for(std::chrono::seconds(1));
- }
-
- int main() {
- std::cout << "starting first helper...\n";
- std::thread helper1(foo);
- helper1.join();
- }
- void f(int i, std::string const& s);
- std::thread t(f, 3 "hello");
注意:参数会以默认的方式被复制到内部存储空间,直到使用的时候才会转成对应的类型。
下面的例子有问题吗?有什么问题?
- void f(int i, std::string const& s);
- void oops(int some_param)
- {
- char buffer[1024];
- sprintf(buffer, "%i", some_param);
- std::thread t(f, 3, buffer);
- t.detach();
- }
局部变量buffer
的指针会被传递给新线程,如果oops()
在buffer
被转换成string
之前退出,那么会导致未定义的行为。解决之道是在构造std::thread
的时候传递string
变量。std::thread t(f, 3, std::string(buffer));
因为默认会复制,如果像要传递引用,需要使用std::ref()
来标识,就像std::bind()
那样。
- std::thread t(update_data_for_widget, w, std::ref(data));
- #include <thread>
- #include <string>
- class CRunner
- {
- public:
- void run0(){}
- void run1(int a) {}
- void run2(int a, int b) {}
- int run3(int a, char b, const std::string& c) {return 0;}
- int run4(int& a, double b, float c, char d) { ++a; return 0; }
- static void run_static(int a) {}
- };
-
- int main()
- {
- CRunner runner;
- int a = 0;
-
- std::thread t0(std::mem_fun(&CRunner::run0), &runner);
-
- std::thread t1(std::mem_fun_ref(&CRunner::run1), std::ref(runner), 1);
-
- std::thread t2(std::mem_fn(&CRunner::run2), std::ref(runner), 1, 2);
-
- std::thread t3(std::bind(std::mem_fn(&CRunner::run3), &runner, 1, 2, "data"));
-
- std::thread t4(std::mem_fn(&CRunner::run4), &runner, std::ref(a), 2.2, 3.3f, ‘d‘);
-
- std::thread t5(&CRunner::run_static, 1);
-
- t0.join();
- t1.join();
- t2.join();
- t3.join();
- t4.join();
- t5.join();
- }
参考资料