多线程学习资源
C++11 多线程(std::thread)详解
之后笔记总结自如上教程。
还是要非常感谢那些花费大量时间编写技术博客,免费分享学习技术的博主、大佬。
这便是作为程序员开放共享的精神吧。
头文件
#include <thread>
构造函数
thread 进程名称(函数名,函数参数1,函数参数2,...);//初始化构造函数
thread 进程名称();//默认构造函数
thread 进程名称1 = thread(函数名,函数参数1,函数参数2,...);//移动构造函数,复制的进程会破坏原有的进程,相当于做了线程的移动
使用
//无参函数
void doit() { cout << "World!" << endl; }
//有参函数
void countnumber(int id, unsigned int n) {
for (unsigned int i = 1; i <= n; i++);
cout << "Thread " << id << " finished!" << endl;
}
//模板+引用参数
template<class T> void changevalue(T &x, T val) {
x = val;
}
//函数调用
int main(){
thread a( []{cout << "Hello, " << flush;} );
thread b(doit);
thread th[10];
thread th1[100];
for (int i = 0; i < 10; i++)
th[i] = thread(countnumber, i, 100000000);
for (int i = 0; i < 100; i++)
th1[i] = thread(changevalue<int>, ref(nums[i]), i+1);
}
- 函数可以只用
lamada
表达式。 - 因为
doit
函数没有参数,故b
线程中doit
后面没有函数参数。 - 可以构造线程组
thread th[10];
再用移动构造赋值。 - 构造函数的第一个参数必须是函数,不能是模板,所以必须显式声明。
- thread的参数传递使用的是右值引用
template <class Fn, class… Args> explicit thread(Fn&& fn, Args&&… args)
(右值引用的相关内容可以参照这里)。因此传参必须传入右值。 std::ref(x)
用于按引用传递对象x
给std::bind
或std::thread
的构造函数。(本人没能很好地理解,只能当作固定搭配了😔)。
join函数
- 线程是在thread对象被定义的时候开始执行的,调用join函数只是阻塞等待线程结束并回收资源。
- 没有执行join或detach的线程在程序结束时会引发异常
多线程操作同一个变量
直接操作会导致变量出错,因此引入std::atomic
和std::mutex
。
具体细节看顶部链接