1. 线程
线程是操作系统能够进行运算调度的最小单位。为了提高任务执行效率,在一些并发编程中,我们经常会使用多线程技术来同步执行一些任务。
线程的主要优势在于它们允许程序进行并发处理。在多核或多处理器的系统中,多线程可以提升应用程序的性能,因为不同的线程可以并行执行。即便在单核处理器上,通过线程的时间分片(时间片轮转),操作系统也能提供多任务并发执行的感觉,这样可以使应用程序更加响应,提高资源的利用率。
C++中为我们提供了语言级的线程库std::thread,实现了对线程的高级管理功能。
std::thread 属于 <thread> 头文件中的一部分,它允许你在程序中创建和控制线程。使用 std::thread 可以把函数或者函数对象作为线程的执行体,线程开始执行时,这个函数或函数对象就会被调用。
接下来,我们利用最简单的描述,介绍利用std::thread启动线程及传参。
2. 线程启动
(1)使用函数指针启动线程
//函数指针可以是可调用对象,传递给 std::thread 构造函数以初始化线程。
void foo(param)
{
...
}
// The parameters to the function are put after the comma
std::thread thread_obj(foo, params);
(2)使用 Lambda 表达式启动线程
//定义一个lambda表达式
auto f = [](params)
{
...
};
//使用 lambda 表达式作为可调用对象来启动
std::thread thread_object(f, params);
(3)使用函数对象启动线程
// 定义一个函数对象
class fn_object_class {
// 重载operator()
void operator()(params)
{
...
}
}
std::thread thread_object(fn_object_class(), params);
(4)使用非静态成员函数启动线程
// 定义一个类
class Base {
public:
// 非静态成员函数
void foo(param) { ... }
}
//创建Base类对象b
Base b;
// 第一个参数是类非静态成员函数的引用
// 第二个参数类对象的引用
// 第三个参数是非静态成员函数的参数
std::thread thread_obj(&Base::foo, &b, params);
(5)使用静态成员函数启动线程
// 定义一个类
class Base {
public:
//静态成员数
static void foo(param) { ... }
}
//创建Base类对象b
Base b;
// 其一个参数是类静态成员函数的引用
// 第二个参数是该函数的参数
std::thread thread_obj(&Base::foo, params);
(6)在类内部创建线程
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <thread>
class demo
{
public:
demo(int a){
reserved = a;
}
~demo(){
}
void eval_display()
{
while(1){
static int count = 0;
printf("reserved: %d\n", reserved);
sleep(1);
count++;
if(count == 50){
break;
}
}
}
int launch(){
t = std::thread(&demo::eval_display, this);
pthread_setname_np(t.native_handle(), "demo");
return 0;
}
int join(){
if(t.joinable()){
t.join();
}
return 0;
}
private:
int reserved;
std::thread t;
};
int main(int argc, char* argv[])
{
demo* d = new demo(12);
d->launch();
d->join();
printf("task complete!\n");
return 0;
}
3. 函数传参
(1)传递简单数据
int a = 10;
void thread_func(int params){}
std::thread t0(thread_func, a);
(2)传递简单数据引用(慎用detach)
int a = 10;
void thread_func(int& params){}
std::thread t0(thread_func, std::ref(a));
(3)传递指针(慎用detach)
int a = 10;
int* a_addr = &a;
void thread_func(int* params){}
std::thread t0(thread_func, a_addr);
(4)传递类对象
参考“传递简单数据”
(5)传递类对象引用(慎用detach)
参考“传递简单数据引用”
(6)传递临时对象
void thread_func(int params){}
std::thread t0(thread_func, 20);