进程:
可以简单理解成一个可执行程序
线程:
一个进程可以包含多个线程,一定有一个主线程。
进程与线程之间的区别与联系:
1)进程是最小的资源分配单位,线程是最小的程序执行单位,每新建立一个进程,系统需要为其分配相应的地址空间,而线程共享数据段,是同一个地址空间,CPU切换一个线程要比切换一个进程花费小很多。
2)进程之间的通信不是很方便,比如经历SOCKET之类的网络编程技术,而线程之间因为是共享数据段所以线程之间的通信很方便很多。
3)多进程程序具有健壮性,具有一定的稳定性,多线程程序只要有一个程序崩溃,整个程序崩溃,而多进程一个程序崩溃,其他程序依然可以保持独立运行。
一 、简单的线程函数
# include
二、将类对象作为线程函数,重载(),初始化类对象将其作为线程函数
# include
三、将某个类中某个函数当作线程函数,初始化类对象以后,第一个参数是对象中的线程函数,第二个函数是类对象名称,需要在前面都加上&。
# include
1)向线程函数传递参数可以在初始化对象的时候,在线程函数后面添加函数参数即可
2)默认线程函数参数传递是值传递,想要传引用,在需要在传参数中加入ref(),并且线程函数要加引用符号。
3)普通引用时候前面需要加const限定符,因为源码初始化的时候是右值引用因此要加const。
4)当类成员函数指针作为线程函数时,可以直接更改对象的数据,与引用的意义相同,若需要参数则在对象后面添加。
void changebyref( int& a){a++;}void changebyref( int& a){a++;}int main(){ int num = 1;std::thread function1(changebyref, ref(num));cout << "nums is " << num << endl;function1.join();cout << "nums is " << num << endl;}
类成员函数指针作为线程函数
class Thread_function{int a;int b;public:void set_a(int a_) { a = a_; }void set_b(int b_) { b = b_; }void sum() { cout << "值为 " << a + b << endl; }Thread_function(int a_ = 0, int b_ = 0) :a(a_), b(b_){}};int main(){ Thread_function rui;std::thread fun_1(&Thread_function::set_a, &rui,20);std::thread fun_2(&Thread_function::set_b, &rui,20);fun_1.join();fun_2.join();rui.sum();}
批量创建线程以及线程所有权的转移void count1(int a){cout << "此时的a 是 " << a << endl;}int main(){ vector
转移线程所有权使用Move