PS:仅供自己记录笔记,使用到时进行记录,不具有参考性。
1. 并发、进程、线程基本概念
- 进程:运行一个程序。
- 线程:每个进程都有一个主线程(main函数的道路),用来执行代码的。通过自己写的代码可以创建其他线程。每个线程都需要一个独立的堆栈空间(1M),线程之间的切换要保存很多中间状态,切换会耗费本该属于程序的运行时间。
- 并发:通过多个进程实现并发。在单独的进程中,创建多个线程实现并发,自己写代码创建除了主线程之外的其他线程。多线程并发:在单个进程中,创建了多个线程。
- 总结:线程启动速度更快,更轻量级;系统资源开销少,执行速度更快。但要注意处理数据的一致性问题。
(1) 线程
- 即使一条线被堵住了,另外一条线也可以走。如myprint打印的后最后打印的互不影响。
- 一般主线程先等到子线程运行完毕后,自己才能最终退出。
#include<thread>
void myprint()
{
std::cout<< "线程开始执行~" << std::endl;
std::cout<<"线程执行结束~" << std::enddl;
}
int main()
{
thread mytobj(myprint);
if (mytobj.joinable())
{
}
// 阻塞主线程,并等待myprint子线程执行完,一起往下执行。
mytobj.join(); // 主线程阻塞到这里等待myprint()执行完。
//mytobj.detach();
std::cout<< " I Love China!" << std::endl;
return 0;
}
-
detach()
:分离,主线程不和子线程汇合了,主线程不等子线程执行完汇合了,各自执行自个的。detach后这个子线程会驻留在后台,被C++运行时库接管,执行完后有运行时库负责清理该线程的相关资源(守护线程)。detach后就不能再join了。 -
joinable()
:判断是否可以成功使用join()或者detach(), 返回true或者false, 返回true说明可以进行join和detach操作,false则不能。 -
线程中传入类对象,这个类对象实际上是被复制到线程中去。
-
使用lambda表达式创建线程。
-
建议不使用detach(),只使用join(),这样就不存在局部变量失效导致线程对内存的非法引用问题。
-
线程id:每个线程都有一个id,通过
std::this_thread::get_id()
来获取。