建设部网站打不开,科技网站 网站建设,无限免费视频在线看,网站搜索排名和什么有关系多线程编程使我们的程序能够同时执行多项任务。
在C11以前#xff0c;C没有标准的多线程库#xff0c;只能使用C语言中的pthread#xff0c;在C11之后#xff0c;C标准库中增加了thread类用于多线程编程。thread类其实是对pthread的封装#xff0c;不过更加好用#xff…多线程编程使我们的程序能够同时执行多项任务。
在C11以前C没有标准的多线程库只能使用C语言中的pthread在C11之后C标准库中增加了thread类用于多线程编程。thread类其实是对pthread的封装不过更加好用现在已经广泛用于C多线程编程。
C11的多线程库主要包含thread mutex atomic condition_variable future等头文件这篇文章只要整理记录thread头文件的内容。
thread头文件中主要就是定义了thread类thread主要的public接口有以下几个 1. 构造函数---创建线程
thread类提供了默认构造函数移动构造函数和一般构造函数并且禁止编译器生成拷贝构造函数以及重载 操作符这俩是不允许的。
三种构造函数的原型
//默认构造
thread() noexcept default;
//移动构造
thread(thread __t) noexcept;
//一般构造
templatetypename _Callable, typename... _Args
explicit thread(_Callable __f, _Args... __args);
最常用的是一般构造函数使用一般构造函数创建线程需要传入一个入口函数和这个函数需要的参数说白了就是告诉被创建的线程要去做什么事情如果这个线程有形参需要跟在后边一起传入。
#include unistd.h
#include threadvoid fun(int num) {while (num--){sleep(1);std::cout thread th num std::endl;}
}int main() {std::thread th(fun, 3);if (th.joinable()){th.join();}} 上边的例子中std::thread th(fun, 3);创建了一个线程线程的入口函数就是void fun(int num)这个函数开启线程的时候同时需要把fun需要的参数传进去。
2. get_id
每个线程都有一个唯一的标识符即线程id使用get_id函数可以获取线程的id
get_id返回一个类型为std::thread::id的对象这是一个类它对运算符进行了重载所以可以直接用std::cout打印出来。
#include unistd.h
#include threadvoid fun(int num) {while (num--){
// sleep(1);
// std::cout thread th num std::endl;}
}
int main() {std::thread th(fun, 3);std::cout th.get_id() std::endl;std::cout this_thread::get_id() std::endl;if (th.joinable()){th.join();}
} this_thread是一个命名空间表示当前线程当前线程就是main函数所在的主线程所以thread::get_id()在这里就是主线程的id。
3. join detach
void join();
void detach();
第一个例子中线程开启之后有这样一段代码
if (th.joinable())
{th.join();
}
这段代码意思是等待th线程执行完毕主线程再继续往下执行。
如果把这段代码注释掉会得到这样的结果 这是因为th线程尚未执行完毕主线程就退出了所以th线程被强行中断了而且终端会打印一段错误信息terminate called without an active exception 。
join 和 detach 是线程两种不同的运行方式
join表示等待调用后会阻塞当前线程直到join线程执行完毕调用者才继续往下执行detach表示分离程序不会等待detach线程执行完且程序退出之后detach线程由系统接管继续执行。
4. joinable
bool joinable() const noexcept;
在调用join或者detach之前先判断线程是否joinable是一个良好的习惯。
从一般构造函数创建的线程他们的joinable都是ture可以进行join或者detach而且对线程进行join和detah是必要的这样可以明确告诉程序该怎么调度这个线程避免不必要的错误发生。
具体原因可以看这里。
5. 析构函数
~thread()
{if (joinable()){std::terminate();}}
从析构函数可以看出来如果一个线程在释放的时候还是joinable的那么整个程序都会退出这也是为什么线程一定要调用join或者detach的原因调用了join和detach之后线程的joinable就为false了。
上边说到join和detach的时候尝试把join删掉了确实会导致程序报错。
6. swap
void swap (thread x) noexcept;
交换两个线程的所有属性。