C++11 并发指南之std::thread 详解
什么是std::thread?
std::thread是C++11提供的用于实现线程的类,它对操作系统的线程进行了封装,提供了一种较为方便、直观的方式来创建、管理和使用多线程程序。
std::thread的使用方法
std::thread的使用需要包含头文件
#include <iostream>
#include <thread>
void func(int x)
{
std::cout << "The parameter passed in is: " << x << std::endl;
}
int main()
{
std::thread t(func, 100);
t.join();//等待子线程完成后再退出主线程
return 0;
}
在上面的示例中,我们通过std::thread的构造函数创建了一个新线程t,并向其中传递了参数100。在新线程中执行的是函数func,该函数打印了参数x的值。由于在主线程中创建的t线程会成为一个独立的线程,因此该程序的输出有可能是乱序的。
同时,我们在主线程中调用了t.join(),该函数会等待线程t的完成后再返回,保证了该程序能够正确的输出结果。
std::thread的其他使用方法
线程的启动方式
std::thread的构造函数提供多种方式来创建线程,最常用的是传递函数指针,但是除此之外,还可以用lambda表达式、std::bind和std::function等方式来创建线程。
以下是使用lambda表达式的示例:
std::thread t([](int x) {std::cout << "Thread running, parameter passed in is: " << x << std::endl;}, 100);
以下是使用std::bind的示例:
void func(int x, const std::string& str)
{
std::cout << str << " The parameter passed in is: " << x << std::endl;
}
int main()
{
std::string str = "Thread running:";
std::thread t(std::bind(func, 100, str));
t.join();
return 0;
}
线程的结束和退出
std::thread的对象有三种状态:
1.默认构造,即对象未与任何线程相关联。
2.与线程相关联,并处于运行状态。
3.与线程相关联,并处于非运行状态(已经执行完毕,或者尚未运行)。
线程结束后,可以调用join或detach来加以处理。
join的作用是等待线程结束后,将线程与主线程的执行流程合并,从而使主线程等待线程结束后再执行下面的操作。以下是join的简单示例:
std::thread t(func);
t.join();//等待线程运行结束后再执行接下来的代码
detach的作用是将线程与主线程分离,即使主线程退出,线程仍可以继续运行。使用detach时要特别注意线程的状态,如果线程已经处于非运行状态,会抛出std::system_error异常。以下是detach的示例:
std::thread t(func);
t.detach();//将线程与主线程分离
线程的管理
std::thread提供了一些成员函数来获取线程的ID、判断线程是否可用、判断线程是否已经执行完成等。
以下是获取线程ID的示例:
std::thread::id id = t.get_id();//获取t线程的ID
std::cout << "Thread id: " << id << std::endl;
以下是判断线程是否可用的示例:
if (t.joinable())//判断t线程是否joinable
{
t.join();
}
示例分析
示例1:
#include <iostream>
#include <thread>
#include <chrono>
void func()
{
std::this_thread::sleep_for(std::chrono::seconds(1));//让线程休眠1秒
std::cout << "Thread running..." << std::endl;
}
int main()
{
std::cout << "Main thread running..." << std::endl;
std::thread t(func);
t.detach();
if (t.joinable())
{
t.join();//如果t线程能够被join,会抛出异常
}
std::cout << "Main thread exiting..." << std::endl;
return 0;
}
在这个示例中,我们创建了一个子线程t,使其执行函数func,然后将线程t与主线程分离(调用t.detach())。在主线程中,我们并没有调用t.join(),因此该程序的输出可能是乱序的,主线程和子线程的执行没有关联。
接着,我们判断了一下线程t是否可用,如果可用,就调用t.join()等待线程t的结束。由于线程t已经被分离,因此判断之后会抛出std::system_error异常。
最后输出了“Main thread exiting...”,主线程可以正常结束。
示例2:
#include <iostream>
#include <thread>
void func(int& x)
{
x++;
}
int main()
{
int x = 0;
std::thread t(func, std::ref(x));//需要使用std::ref函数对x进行引用包装
t.join();
std::cout << "x increment by thread: " << x << std::endl;
return 0;
}
这个示例中,我们创建了一个子线程t,使其执行函数func,并将x的引用传递给该线程。为了正确地传递x,我们使用了std::ref函数对x进行了引用包装。
在函数func中,我们对x进行了递增操作x++,然后线程t运行结束。在主线程中,我们输出了x的值,可以看到子线程确实对x进行了递增操作。
总结
本文主要介绍了std::thread的使用方法、启动方式、线程的结束和退出以及线程的管理等方面,同时给出了两个简单的示例。
std::thread在C++11中提供了一种便捷的方式来实现多线程,相比于传统的操作系统API,std::thread的使用更加方便直观,能够提高多线程编程的效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11 并发指南之std::thread 详解 - Python技术站