锁和原子操作是怎么实现的

mutex互斥锁是借助与汇编指令cmpxchgl实现的,是汇编级别的CAS,如果swap不成功,则调用__lll_lock_wait让线程调度,让出cpu。

C++ 标准库std::mutex只是pthread_mutex_t的封装,所以看pthread_mutex_t就可以。

如何调试死锁

写多线程malloc不知道为什么死锁了,记录下调试过程

使用gdb调试,在vscode的调试控制台下使用gdb命令需要加上-exec前缀

运行程序,发现不在打印日志,怀疑死锁,SIGTRAP暂停程序

  • 使用info thread查看线程情况

image-20211112160120456

前面带*的是正在运行的线程,不带*的大概率就是阻塞的线程了,观察后面的栈帧情况,发现程序运行在__lll_lock_wait请求获得锁,说明2、3、4、6、9线程都阻塞在这里了。(LWP后面跟的就是线程号)。

  • 使用thread apply all backtrace查看所有线程的栈帧信息

backtrace是打印栈帧的命令,thread apply all 可以对所有线程使用后面跟随的指令,有lock_wait就是发生了死锁的线程

image-20211112161027819

  • 然后使用thread *切换到不同的线程,打印出mutex变量查看owner的线程号:

image-20211112164309517

  • 检查是否有循环持锁的情况,再检查代码逻辑
  • (最后都是程序逻辑写错了)

参考

https://kernel.taobao.org/2020/11/talking_of_atomic_operations/

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×