手机网站制作流程,wordpress菜单和导航栏,专门做mmd的网站,金华电子商务网站建设文章目录 Windows和Linux平台的线程线程构造函数模板参数包 最近发现C11的线程库还没有进行总结#xff0c;因此本篇对于C11当中新增的线程库的一些基本用法进行总结
Windows和Linux平台的线程
在Linux平台下是存在一些原生的线程系统调用的#xff0c;比如有pthread_creat… 文章目录 Windows和Linux平台的线程线程构造函数模板参数包 最近发现C11的线程库还没有进行总结因此本篇对于C11当中新增的线程库的一些基本用法进行总结
Windows和Linux平台的线程
在Linux平台下是存在一些原生的线程系统调用的比如有pthread_create这样的系统调用而在C11标准之后C自己的标准库中也出现了有关线程的调用库这样最大的好处就是只要使用的是C提供的线程库这样不管是在Linux下还是在Windows下都是可以使用的提供了一个跨平台的好处因为这本身是属于语言本身的
对于线程库当中的实现其实就是把这样的类unix平台的接口和Windows的原生接口进行了一个条件编译当检测到时WIN32的系统的时候就使用的是Windows提供的原生的线程而如果识别到时unix的系统就使用unix提供的线程具体可以理解为下面这样
#ifdef _WIN32
CreateThread()
#else
pthread_create()
#endif线程
C语言本身提供的这个线程是一个用类进行封装的线程 也提供了一些成员函数 构造函数
对于一个类来说首先要看一下它的构造函数看一下可以用什么样的方法来构造出这个函数 在上面的这四种构造函数中出现了一些熟悉的身影默认构造函数是一个无参的构造函数表示的是一个空线程不启动其次是一个模板在这个模板中带有的是一个可变参数包并且还有万能引用等这些后续进行代码实践需要注意的是其中的Fn表示的是一个可执行对象可以是函数指针仿函数lambda表达式包装器等等
从下面的拷贝函数可以看出线程不支持拷贝构造但是支持移动构造
模板参数包
为什么要诞生出这个模板参数包来进行构造函数先看看Linux下的线程创建是怎么创建的 如图所示的是Linux下的线程创建的系统调用第一个参数是线程的tid这里就不多介绍了重点是后面的函数指针后面的arg表示的是函数指针的参数那这就意味着会用到强转这样的信息来进行参数的解析如果使用原生的方式要传递多个参数通常要把这些信息放到一个结构体当中
#include iostream
#include unistd.h
#include string
using namespace std;struct thread_data
{thread_data(const string message, int id) : _message(message), _id(id) {}string _message;int _id;
};void *routine(void *arg)
{struct thread_data *td (struct thread_data *)arg;cout td-_message : td-_id endl;return nullptr;
}int main()
{pthread_t tid;for (int i 0; i 5; i){thread_data td(这是线程, i);pthread_create(tid, nullptr, routine, (void *)td);pthread_join(tid, nullptr);}return 0;
}而在C11的库当中如果使用这个模板参数包就可以很方便的直接进行使用了
#include iostream
#include thread
#include windows.h
#include functional
using namespace std;void func1(const string message, int id)
{cout message id endl;
}struct func3
{void operator()(const string message, int id){cout message id endl;}
};int main()
{// 使用函数指针string tmp1 这是函数指针的方法;int id1 1;thread t1(func1, tmp1, id1);Sleep(1000);// 使用lambda表达式string tmp2 这是lambda的方法;int id2 2;thread t2([](const string message, int id) {cout message id endl;}, tmp2, id2);Sleep(1000);// 使用仿函数string tmp3 这是仿函数的方法;int id3 3;func3 f3;thread t3(f3, tmp3, id3);Sleep(1000);// 使用包装器functionvoid(const string, int) func4 func1;string tmp4 这是包装器的方法;int id4 4;thread t4(func4, tmp4, id4);Sleep(1000);// 回收等待t1.join();t2.join();t3.join();t4.join();return 0;
}如上所示是四种可执行方式调用线程的方式