mac開(kāi)發(fā)系列32:NSLock死鎖場(chǎng)景

今天有用戶(hù)反饋,mac微信卡死在登錄界面,彩球一直轉(zhuǎn)。從現(xiàn)象來(lái)看,是主線程卡住了,難道是死循環(huán)了?進(jìn)一步地,開(kāi)啟調(diào)試符號(hào)("Build Settings"->"Strip Linked Product"置為NO),發(fā)現(xiàn)console里面狂刷主線程卡頓監(jiān)控日志,主要堆棧如下:

      [I][][MMLagMonitor.mm, startMonitorWithCallback, 179]][INFO: Backtrace of Thread 775:
      libsystem_kernel.dylib 0x7fff9a50ac22 __psynch_mutexwait + 10
      Foundation 0x7fff866710e2 -[NSLock lock] + 145
      WeChat 0x108e7bc68 -[MMCGINotifyCenter addDelegateInternal:sessionId:] + 59
      WeChat 0x108e7bbef +[MMCGINotifyCenter addDelegate:sessionId:] + 83
      WeChat 0x108a03630 -[MMCGI registerDelegate:] + 37
      WeChat 0x108a034d8 -[MMCGI initWithItem:delegate:] + 140
      WeChat 0x10889a16d -[MMCGIService RequestCGI:delegate:] + 302
      WeChat 0x108e29126 -[AuthCGI QRCodeAuth:withPassword:] + 3859
      WeChat 0x108e9c1d0 -[AccountService QRCodeLoginWithUserName:password:] + 58
      WeChat 0x108dc5039 __34-[QRCodeLoginLogic setupQRCodeCGI]_block_invoke.38 + 330
      WeChat 0x108b3f1e3 -[QRCodeLoginCG<…>

可以看到,NSLock一直在鎖等待,即死鎖了。 那么死鎖是怎么發(fā)生的呢?我們知道,NSLock是非遞歸鎖,當(dāng)同一線程重復(fù)獲取同一非遞歸鎖時(shí),就會(huì)發(fā)生死鎖。如下所示:

      NSLock *m_lock;
      [m_lock lock]; // 成功上鎖
      do something....
      [m_lock lock]; // 上面已經(jīng)上鎖,這里阻塞等待鎖釋放,不會(huì)再執(zhí)行下面,鎖永遠(yuǎn)得不到釋放,即死鎖
      do something....
      [m_lock unlock]; // 不會(huì)執(zhí)行到
      do something....
      [m_lock unlock];

   于是,斷點(diǎn)跟蹤堆棧中相關(guān)問(wèn)題函數(shù)的調(diào)用關(guān)系,企圖找到如上所示的嵌套上鎖代碼,結(jié)果如下:


簡(jiǎn)化如下:

        - (void)erase { 
        [m_lock lock]; 
        dealloc(); 
        [m_lock unlock];
        }
        - (void)dealloc { 
            erase();
        }

另一方面,用NSRecursiveLock或者@synchronized替代NSLock,就可以成功登錄了。因?yàn)橥痪€程重復(fù)獲取同一遞歸鎖,不會(huì)發(fā)生死鎖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容