std::thread
C++ 11 提供的 std::thread 类
无论是 Linux 还是 Windows 上创建线程的 API,都有一个非常不方便的地方,就是线程函数的签名必须是固定的格式(参数个数和类型、返回值类型都有要求)。C++11 新标准引入了一个新的类std::thread(需要包含头文件<thread>),使用这个类的可以将任何签名形式的函数作为线程函数。以下代码分别创建两个线程,线程函数签名不一样:
#include <stdio.h> #include <thread> void threadproc1() { while (true) { printf("I am New Thread 1!\n"); } } void threadproc2(int a, int b) { while (true) { printf("I am New Thread 2!\n"); } } int main() { //创建线程t1 std::thread t1(threadproc1); //创建线程t2 std::thread t2(threadproc2, 1, 2); while (true) { //Sleep(1000); //权宜之计,让主线程不要提前退出 } return 0; }当然,std::thread在使用上容易犯一个错误,即在std::thread对象在线程函数运行期间必须是有效的。什么意思呢?我们来看一个例子:
#include <stdio.h> #include <thread> void threadproc() { while (true) { printf("I am New Thread!\n"); } } void func() { std::thread t(threadproc); } int main() { func(); while (true) { //Sleep(1000); //权宜之计,让主线程不要提前退出 } return 0; }上述代码在func中创建了一个线程,然后又在main函数中调用func方法,乍一看好像代码没什么问题,但是在实际运行时程序会崩溃。崩溃的原因是,当func函数调用结束后,func中局部变量t(线程对象)被销毁了,而此时线程函数仍然在运行。这就是我所说的,使用std::thread类时,必须保证线程函数运行期间,其线程对象有效。这是一个很容易犯的错误,解决这个问题的方法是,std::thread对象提供了一个detach方法,这个方法让线程对象与线程函数脱离关系,这样即使线程对象被销毁,仍然不影响线程函数的运行。我们只需要在在func函数中调用detach方法即可,代码如下:
//其他代码保持不变,这里就不重复贴出来了 void func() { std::thread t(threadproc); t.detach(); }然而,在实际编码中,这也是一个不推荐的做法,原因是我们需要使用线程对象去控制和管理线程的运行和生命周期。所以,我们的代码应该尽量保证线程对象在线程运行期间有效,而不是单纯地调用detach方法使线程对象与线程函数的运行分离。