个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《Linux》
文章目录
- 前言
- 一、线程的总结
- 1. 线程的优点
- 2. 线程的缺点
- 3. 线程异常
- 4.线程和进程
- 二、线程的控制
- 创建线程
- 线程终止
- 线程等待
- 获取返回值
- 线程分离
- 总结
前言
本文作为我对于线程的简单总结,线程控制的知识总结
一、线程的总结
1. 线程的优点
- 创建一个新线程的代价比创建一个新进程小的多
- 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要小
- 线程占有的资源要比进程少很多
- 能充分利用多处理器的可并行数量(并行,多个执行流在同一时刻拿着不同的CPU继续运算,执行代码)
- 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务
- 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现
- I/O密集型应用(如下载,上传),为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作
创建线程并不是越多越好,进程的执行效率,一定随着线程的数量增多,效率为正态分布的(线程的切换)。线程的个数最好 = CPU的个数 * CPU的核数
2. 线程的缺点
- 性能损失:一个很少被外部事件阻塞的计算密集型线程往往无法与其他线程共享同一个处理器,如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,如增加了额外的同步和调度开销,而可用的资源不变
- 健壮性(鲁棒性)降低:编写多线程需要全面更深入的考虑,在一个多线程程序里,因时间分配的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,也就是说线程之间是缺乏保护的
- 缺乏访问控制:因为线程共享地址空间,那一个线程定义的局部变量 or new出的空间,其它线程也能使用,这就导致一个线程可能会不小心修改另一个线程正在使用的数据,导致数据不一致、逻辑错误甚至程序崩溃
- 编程难度提高:编写与调试一个多线程程序比单线程程序困难
3. 线程异常
- 单个线程如果出现除0,野指针问题导致线程崩溃,进程也会崩溃
- 线程是进程的执行分支,线程出异常,就类似进程出异常,进而触发信号机制,终止进程,进程终止,该进程内的所有线程也全部终止
创建5个线程,其中线程thread-4触发除0异常。
#include #include #include #include #include #include #include using func_t = std::function; const int threadnum = 5; class ThreadDate { public: ThreadDate(const std::string &name, const uint64_t &time, func_t f) : threadname(name), createtime(time), func(f) { } public: std::string threadname; uint64_t createtime; func_t func; }; void Print() { std::cout ThreadDate *td = static_cast std::cout std::cout std::vector char threadname[64]; snprintf(threadname, sizeof(threadname), "%s-%d", "thread", i); pthread_t tid; ThreadDate *td = new ThreadDate(threadname, (uint64_t)time(nullptr), Print); pthread_create(&tid, nullptr, threadRoutine, (void *)td); pthreads.push_back(tid); sleep(1); } while (true) { std::cout