C++面试八股文:如何避免死锁?

这篇具有很好参考价值的文章主要介绍了C++面试八股文:如何避免死锁?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

某日二师兄参加XXX科技公司的C++工程师开发岗位第31面:

面试官:什么是锁?有什么作用?

二师兄:在C++中,锁(Lock)是一种同步工具,用于保护共享资源,防止多个线程同时访问,从而避免数据竞争和不一致。

面试官:有哪些锁?

二师兄:从种类上分,可以分为普通锁、读写锁、递归锁等种类。

二师兄:从实现上分,可以分为互斥锁、自旋锁、信号量、条件变量等。

面试官:互斥锁如何使用?

二师兄:在C++11之前,C++便准层面并没有定义锁,锁的应用要依赖于平台。Linux下使用pthread库中的mutex

#include <pthread.h>
pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mutex_);
//被保护的区域
pthread_mutex_unlock(&mutex_);

二师兄:C++11引入了std::mutex,统一了各个平台上互斥锁的使用:

#include <mutex>
std::mutex mutex_;
mutex_.lock();
//被保护的区域
mutex_.unlock();

面试官:pthread_mutexstd::mutex有没有非阻塞的api

二师兄:有的,分别是pthread_mutex_trylock()try_lock(),当获取不到锁时这两者并不阻塞当前线程,而是立即返回。需要注意的是,当pthread_mutex_trylock()获取到锁时返回0,而std::mutex::try_lock()方法获取不到锁时返回false

面试官:std::lock_guardstd::unique_lock用过吗?

二师兄:用过。

面试官:两者有什么相同点和不同点?

二师兄:相同点是两者都使用RAII(资源获取即初始化)技术实现的锁,支持自动上锁,自动解锁。

二师兄:不同点主要包括三个方面:

1.灵活性:std::unqiue_lock的灵活性要高于std::lock_guradstd::unique_lock可以在任何时间解锁和锁定,而std::lock_guard在构造时锁定,在析构时解锁,不能手动控制。

2.所有权:std::unique_lock支持所有权转移,而std::lock_gurad不支持。

3.性能:由于std::unique_lock的灵活性更高,它的性能可能会稍微低一些。

面试官:能实现一个lock_gurad吗?

二师兄:我尝试一下:

class lock_guard
{
    explicit lock_guard(std::mutex& m):mutex_(m)
    {
        mutex_.lock();
    }
    ~lock_guard()
    {
        mutex_unlock();
    }
private:
    std::mutex& mutex_;
};

面试官:为什么会发生死锁?

二师兄:当进程A持有锁1请求锁2,进程B持有锁2请求锁1时,两者都不会释放自己的锁,两者都需要对方的锁,就会造成死锁。当然现实中可能比这要复杂,但原理是相同的。

面试官:如何避免死锁?

二师兄:主要从以下几个方面入手:

1.避免循环等待,如果需要在业务中获取不同的锁,保证所有业务按照相同的顺序获取锁。

2.使用超时锁,当锁超时时,自动释放锁。

3.使用try_lock,当锁被占用时,返回false并继续执行。

4.锁的粒度尽量要小,只保护竟态数据而不是整个流程。

面试官:知道adopt_lock_t/defer_lock_t/try_to_lock_t这三种类型的用法吗?

二师兄:额。。不知道。。

面试官:好的,回去等通知吧。

让我们来看看最后一个问题:

知道adopt_lock_t/defer_lock_t/try_to_lock_t这三种类型的用法吗?

adopt_lock_t/defer_lock_t/try_to_lock_t都是空类,主要表示std::lock_guradstd::unqiue_lock的默认构造中的操作:

adopt_lock_t:默认互斥量已被当前线程锁定,不使用lock()方法对互斥量加锁:

std::mutex mtx_;
mtx_.lock();	//lock
{
    std::lock_guard<std::mutex> lock_(mtx_,std::adopt_lock);	//这里默认当前线程已经对mtx_加过锁
    ...
}//unlock

defer_lock_t:虽然我拥有了std::mutex的引用,但是在构造函数中并不调用lock()方法对互斥量加锁:

std::mutex mtx_;
{
    std::unique_lock<std::mutex> ulock_(mtx_,std::defer_lock);	//这里并没有加锁
    ulock_.lock();
    if(ulock_.owns_lock())
    {
		//locked
    }else
    {
		//unlocked
    }
}//if locked,unlock

try_to_lock_t:在构造函数执行是并不是使用lock()方法加锁,而是使用try_lock()方法加锁:

std::mutex mtx_;
{
    std::unique_lock<std::mutex> ulock_(mtx_,std::try_to_lock);	//这里mtx_如果没有被锁定,则加锁成功,否则加锁失败
    if(ulock_.owns_lock())
    {
		//locked
    }else
    {
		//unlocked
    }
}//if locked,unlock

adopt_lock_t可以用于std::lock_guradstd::unique_lock,而defer_lock_t/try_to_lock_t只能用于std::unique_lock

关注我,带你21天“精通”C++!(狗头)文章来源地址https://www.toymoban.com/news/detail-519683.html

到了这里,关于C++面试八股文:如何避免死锁?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++面试八股文:如何在堆上和栈上分配一块内存?

    某日二师兄参加XXX科技公司的C++工程师开发岗位6面: 面试官: 如何在堆上申请一块内存? 二师兄:常用的方法有malloc,new等。 面试官:两者有什么区别? 二师兄:malloc是向操作系统申请一块内存,这块内存没有经过初始化,通常需要使用memset手动初始化。而new一般伴随三个

    2024年02月08日
    浏览(47)
  • C++面试八股文:std::vector和std::list,如何选择?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第24面: 面试官: list 用过吗? 二师兄:嗯,用过。 面试官:请讲一下 list 的实现原理。 二师兄: std::list 被称为双向链表,和C中手写双向链表本质上没有大的区别。 list 对象中有两个指针,一个指向上一个节点( node ),一

    2024年02月10日
    浏览(39)
  • C++面试八股文:技术勘误

    不知不觉,《C++面试八股文》已经更新30篇了,这是我第一次写技术博客,由于个人能力有限,出现了不少纰漏,在此向各位读者小伙伴们致歉。 为了不误导更多的小伙伴,以后会不定期的出勘误文章,请各位小伙伴留意。 在《C++面试八股文:C++中,设计一个类要注意哪些东

    2024年02月11日
    浏览(50)
  • C++面试八股文:什么是RAII?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第13面: 面试官:什么是 RAII ? 二师兄: RAII 是 Resource Acquisition Is Initialization 的缩写。翻译成中文是资源获取即初始化。 面试官: RAII 有什么特点和优势? 二师兄:主要的特点是,在对象初始化时获取资源,在对象析构时释放

    2024年02月08日
    浏览(56)
  • C++面试八股文:聊一聊指针?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第17面: 面试官:聊一聊指针? 二师兄:好的。 面试官:你觉得指针本质上是什么? 二师兄:这要从内存地址开始说起了。如果有一块容量是1G的内存,假设它的地址是从 0x00000000 到 0x3fffffff ,每一个字节都对应一个地址。当

    2024年02月09日
    浏览(38)
  • C++面试八股文:什么是智能指针?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第19面: 面试官:什么是智能指针? 二师兄:智能指针是C++11引入的类模板,用于管理资源,行为类似于指针,但不需要手动申请、释放资源,所以称为智能指针。 面试官:C++11引入了哪些智能指针? 二师兄:三种,分别是 s

    2024年02月09日
    浏览(44)
  • C++面试八股文:用过STL吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第21面: 面试官:用过STL吗? 二师兄:(每天都用好吗。。)用过一些。 面试官:你知道STL是什么? 二师兄:STL是指标准模板库( Standard Template Library ),是C++区别于C语言的特征之一。 面试官:那你知道STL的六大部件是什么

    2024年02月09日
    浏览(47)
  • C++面试八股文:了解位运算吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第12面: 面试官:了解位运算吗? 二师兄:了解一些。(我很熟悉) 面试官:请列举以下有哪些位运算? 二师兄:按位与( )、按位或( | )、按位异或( ^ ),按位取反( ~ )、左移( )和右移( )。 面试官:好的。那你

    2024年02月08日
    浏览(41)
  • C++面试八股文:什么是构造函数?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第29面: 面试官:什么是构造函数? 二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类的名称相同,并且没有返回类型。构造函数在对象被创建时自动调用。 面试官:什么是默认构造

    2024年02月11日
    浏览(47)
  • C++面试八股文:std::vector了解吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第23面: 面试官: vector 了解吗? 二师兄:嗯,用过。 面试官:那你知道 vector 底层是如何实现的吗? 二师兄: vector 底层使用动态数组来存储元素对象,同时使用 size 和 capacity 记录当前元素的数量和当前动态数组的容量。如果

    2024年02月10日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包