diff --git a/exampleSite/content/post/2024-04-19面试复盘/index.zh-cn.md b/exampleSite/content/post/2024-04-19面试复盘/index.zh-cn.md index f5f2da8..80d200d 100644 --- a/exampleSite/content/post/2024-04-19面试复盘/index.zh-cn.md +++ b/exampleSite/content/post/2024-04-19面试复盘/index.zh-cn.md @@ -246,6 +246,71 @@ auto_ptr是C++98中引入的第一个智能指针,但是由于他的不安全 加锁:**互斥锁**,**读写锁**,cpp中特有的智能锁 +死锁; + +- 产生的条件:互斥,请求保存,不可抢占,循环等待 + +- 可能产生的情况分为两种: + + + + 1)第一种是:用到了一把锁造成的死锁,产生的原因是操作失误,加了锁后忘记解锁了 + 或者是一把锁被加了两次造成的死锁,你再去解锁就解不开了… + 或者是你在解锁之前,因为满足某种条件提前return了 + + ``` + eg: + void func(){ + 上锁 + if(条件)return; + 解锁 + } + ``` + + + + 说是忘记,但有时候就是容易但这样的错误,而且在项目开发的时候调试起来没那么容易,比如说我们最容易犯的函数循环嵌套的死锁问题;函数a调用了函数b,但是函数a和b内部都用到了同一把锁,保护相同的共享资源,导致一个线程同时上两次锁,这个问题还是比较隐晦的,我遇到过一次 + + + + + + 2)另一种是用到了多把锁, + 当多个线程访问了多块共享资源,就需要多把锁,(共享资源可以是一个全局变量,也可能是一段堆内存,还可能是一个静态资源,或者是在main函数中申请的一段栈空间,因为只要main函数不结束,这个资源就不会被回收,所以也可以做这个共享资源),所以说每个共享资源都需要一把锁。 + 比如说两个共享资源两把锁,资源x被锁a锁住了,资源y被锁b锁住了,在资源x没有解锁的情况下,资源x去访问资源y,而资源y也在没有解锁的情况下去访问资源x,这样就僵持不下 + +- 死锁避免的解决办法: + +1. 第一种方法:你在访问其他共享资源时,需要先把你目前持有共享资源解开。 +2. 第二种方式:在访问共享资源时,不要直接加锁,而是尝试加锁(),因为我们提供的互斥锁里面都有一个trylock,如果尝试失败,你就先等一等,等其他线程解锁后,你再trylock就成功了 +3. 另外,cpp11还提供了lock_guard智能锁,和智能指针管理类似,使用了lock_guard我们就不需要去维护互斥锁的解锁操作。不过,lock_guard管理的是一个大括号这一段代码,假如说这段大括号有100多行代码,使用lock_guard就不太划算,因为锁住的太多了,这个使用还是使用常规锁,不要使用智能锁。 + +--- + +在项目中,我使用的是libevent+线程池,在线程池中有很多子线程,如果有子线程操作共享资源,那么需要加锁, + +这里也是会有一个生产者消费者的概念,任务队列相当于那个容器,不断有生产者线程给任务队列中放任务,也不断有消费者线程从任务队列里面拿任务,生产者线程不只一个,消费者线程也不只一个. + +如果只有一个任务队列,会出现惊群效应:只有一个任务可拿,但是却唤醒了所有的消费者线程,最后只有一人能够拿到这个任务,其他消费者都是无效唤醒 + +为了解决这个"惊群效应",我们采用建立多个任务队(有多少个线程,就创建多少个任务队列),每个线程都有属于自己的任务队列,那么此时就不再出现线程与线程之间的竞争了(就和libevent+线程池一样,每个线程都有属于自己的事件集合,为的就是避免线程竞争),既然该任务队列被一个线程独占,那么就不存在竞争了,就无需加锁,他在添加的时候不能处理,他在处理的时候不能添加 + +主线程负责两件事: + +1)负责和新客户端建立连接 + +2)主线程还会给任务队列中添加任务,子线程负责从任务队列中取任务 + + + +--- + +有一个很傻的问题: + + + + + ## 13.死锁 死锁产生的条件: diff --git a/exampleSite/content/post/2024-04-19面试复盘/图片/1713687466179.png b/exampleSite/content/post/2024-04-19面试复盘/图片/1713687466179.png new file mode 100644 index 0000000..cfc2628 Binary files /dev/null and b/exampleSite/content/post/2024-04-19面试复盘/图片/1713687466179.png differ