(笔记demo)Linux系统编程 线程部分笔记

本文深入探讨了线程的概念,包括线程与进程的区别、线程间的资源竞争以及如何通过锁、信号量和条件变量进行同步控制。重点讨论了死锁问题及其解决方案,并介绍了线程池的管理和设计。此外,还阐述了线程数量与CPU核心线程数的关系,以优化多线程效率。
摘要由CSDN通过智能技术生成

1. 线程是程序的最小运行单元,代码段只是数据

2. 和进程类似,线程也存在资源竞争,在不做管控的情况下,你并不会知道哪一个线程先运行

3. 线程没有主次之分,但是进程结束,线程也就结束,所以进程的那条线程可以认为是‘主’线程

4. 每条线程都拥有自己的寄存器和栈段,所以当线程结束后,线程内的数据也会被释放

5. 线程之间的通信:句柄思想、共享空间、返回值、传出参数、全局变量等等

线程管控↓线程管控↓线程管控↓

6. 锁:线程中最重要的概念之一,管理线程

        多线程同时对统一全局变量进行修改时,会经历,读->改->写,三步

        例:两个线程同时读了一个变量a到自己的寄存器,然后a+1,然后把修改后的a传回内存,a等于6,但实际上设计者希望a=7,因为a加了2次

        锁会将读改写三步合成一个原子操作,并且其他线程等待锁的过程也可以设置阻塞

        但同一个锁的资源只有一个

        锁住的操作应该尽量为O(1)级

7. 死锁:当一个锁被线程占用时,申请该锁会导致线程进入阻塞等待,即便自己正在使用这个锁,

        例:拿着手机找手机

        解决方案:尽量不使用多个锁,使用多个锁也需按严格按顺序使用,设计程序时不断设想是否会造成死锁,也可以使用非阻塞申请锁

8. 信号量:锁的升级版,可以自己设置资源量,也就是多个锁

        信号量通过变量控制多线程

                例:信号量a初始化为3,此时两个线程等待信号量a,信号量全开放,两个线程收到信号同时运行,信号量a减至1

        信号量不仅可以用于同一进程之中的线程,还可以跨进程使用,非常强大

9. 条件变量:通过一个变量响应程序操作,可以管理线程执行顺序的切换

        可以暂时释放锁,使得其他线程可以使用锁,在其他线程响应当前线程的条件变量后,该线程会重新抢锁,再继续运行,此处存疑,如果条件变量被响应时,无锁可抢会怎样?

解答:会进入阻塞等待锁资源的状态,多个线程同时等待就会进入一个等待队列,顺序依靠竞争,同时锁数量会进行p操作而变为负数,,详细查看 pv操作 笔记

此外:条件变量的响应通常伴随惊群效应,即多个线程同时响应一个条件变量,产生竞争,而与此同时诞生的“无效响应”应当避免,详见↓

        当一个线程执行条件变量等待时,释放的锁可能会被抢占进而进行等待同一个条件变量的响应,此时如果该条件变量响应后只能支持一个被响应的线程运行,那么其他被响应的线程就会产生“无效响应”,因为产生响应的变量只能支持一个线程使用,而该线程使用后,释放锁,其他线程抢锁,然后继续响应该变量,但该变量已经被使用过了,此时正确的流程应该是重新等待响应,所以应该在抢到锁后再进行一次变量判断,判断该变量在此之前是否已经被其他线程使用过了,是否还能继续使用,如果不能,就重新等待响应

                总结↑:多线程竞争资源时,即使等到了条件变量的响应,也可能不是第一次被响应了,如果程序目的是要求该响应只能接收一次,就应该重新等待响应

while(响应线程改变的变量) {
    thread_cond_wait(条件变量,锁);
}
//第二行开始
//1.收到信号
//2.抢到锁
//3.回到循环条件判断该变量是否已经被使用过
//4.被使用过,已经不符合要求,重新等待
//4.未被使用过,跳出循环,开始执行线程

惊群效应能否避免?

响应变量的signal与broadcast分别表示响应至少一个与所有阻塞全部响应,此处的至少一个的意思是signal响应可以减少响应线程的数量,但是无法完全避免“惊扰”到其他线程,意思就是惊群效应无法从底层完全避免,只能减少,为了确保安全性,还是应该使用上述方法避免惊群效应

10. 线程管理逻辑 常用模板

        关键逻辑:先锁住线程执行,然后多线程执行顺序实现,最后留一个多线程开启的‘开关’

        锁:创建锁->关锁->线程逻辑实现->开锁->进程等待线程结束->毁锁

                线程逻辑实现:抢锁->执行程序->放锁

        信号量:创建信号量->置零->线程逻辑实现->置1->进程等待线程结束->删除信号量

                线程逻辑实现:等待信号量大于零->执行程序->下一个线程的信号量大于零

        条件变量:创建锁->创建条件变量->线程逻辑实现->进程等待线程结束->删除锁->删除条件变量

                线程逻辑实现:抢锁->等待条件变量响应并临时释放锁->执行程序->先释放锁再响应下一个线程的条件变量        :此处如果先响应变量再释放锁会导致被响应的线程无锁可用(待验证)

11.线程池

        线程池其实是,线程与任务池

        当多线程操作多任务时,任务使用数据结构存储,线程从任务池中抢夺任务然后执行

        避免多个线程抢同一个任务:对内存的访问冲突,进行相关锁的设置,应让锁住的程序尽量为O(1)级

        避免线程抢“空”任务:多个线程同时响应一个任务,该任务被一个线程抢走后,其余线程继续争抢,触发段错误,具体解决方法查看9.条件变量

12.线程池的线程数量设计及原因

效率最高的是线程数等于cpu核线程数,如果创建线程高于cpu核线程数,那么在底层就会产生竞争,线程之间竞争cpu的核,大量的竞争会导致效率降低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值