iOS postNotification死锁问题

最近在项目中又遇到了一个死锁问题,跟NSNotificationCenter有关,这个类平时不知道大家有没有注意过,postNotication的时候是加锁的,如果是在主线程注册对应的监听方法,而此时主线程又在等待另一个线程,则会导致发送通知的线程阻塞。如果发送通知的线程跟等待的线程是同一个,就会导致死锁。

具体情况是这样的,我在项目中使用了libevent库,他有两种运行模式:同步和异步。 如果是同步,则所有操作都在一个线程上执行,如果是异步,则在不同线程上执行,为了避免多线程同时访问同一个导致的崩溃,我们申明了对内部线程进行加锁,即evthread_use_pthreads。

然后我们项目里面申明了一个通知kP2PConnectStatusChangeNoti, 这个通知的回调方法是在MGCameraCollectionViewCell的awakeFromNib方法中注册的(主线程),作用是监听P2P连接的状态,显示对应的UI

然后通知发送的代码是在libevent的一个回调方法session_connect_success中,这个回调方法在p2p连接建立成功后执行

我在离开某个页面的时候,会触发destroy方法,这个方法在主线程执行,然后内部会调用libevent的某些方法,这时候问题来了,当我反复操作离开页面,进入页面(会触发p2p连接的建立)多次后,就出现了死锁。见下图,thread 1 在等待libevent释放锁,livevent在等待thread21 的session_connect_success方法执行完成,而thread21在调用setConnectStatus时,发送kP2PConnectStatusChangeNoti对线程进行了加锁,这个锁是NSNotificationCenter内部加的,我没有具体源码,但是猜测应该是锁住了主线程。 为什么这么说呢? 因为从断点时各线程的情况来看,只有thread1 (主线程)和thread21(libevent线程)在wait,其他线程都没有wait,显然是互相等待导致了死锁。 这里需要注意一点,libevent持有的锁跟NSnotificationCenter内部的锁不是同一个。

我们尝试在主线程异步发送kP2PConnectStatusChangeNoti通知,看还会不会死锁。经过实验证明,这样确实不会死锁,因为是异步的,libevent线程不会被主线程阻塞,也就能顺利的完成event的释放,从而主线程也能顺利运行下去。

那为什么NSNotificationCenter要对postNotification加锁呢?我猜我想应该是为了避免发送通知时,有其他线程对观察者进行添加和移除吧,那样会导致一些意想不到的事情发生,或者是为了避免多线程同时操作内部队列引发数据不一致的问题。我觉得前一种可能性更大,同时addObserver方法和removeObserver内部应该也进行了加锁,这样才能更好的处理多线程同时操作。如果是这样的话,就可以解释为什么postNotification会阻塞主线程了,因为在频繁进入和离开页面的时候,频繁调用了addObserver和removeObserver方法,他们主线程上加了锁(严格来说,removeObserver不一定是在主线程调用,因为这里是编译器自己加上去的,我们并没有显示调用),而postNotification在等待他们释放锁,间接引起了发送通知的线程阻塞。

由此,我们可以得出结论,使用NSNotificationCenter时,发送通知和给通知添加观察者的线程最好是同一个,这样可以避免加锁导致的线程阻塞和App卡死。

相关推荐
DisonTangor5 小时前
苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了
ios·chatgpt·iphone
- 羊羊不超越 -5 小时前
App渠道来源追踪方案全面分析(iOS/Android/鸿蒙)
android·ios·harmonyos
2401_8658548821 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
HackerTom1 天前
iOS用rime且导入自制输入方案
ios·iphone·rime
良技漫谈1 天前
Rust移动开发:Rust在iOS端集成使用介绍
后端·程序人生·ios·rust·objective-c·swift
2401_852403551 天前
高效管理iPhone存储:苹果手机怎么删除相似照片
ios·智能手机·iphone
星际码仔2 天前
【动画图解】是怎样的方法,能被称作是 Flutter Widget 系统的核心?
android·flutter·ios
emperinter2 天前
WordCloudStudio:AI生成模版为您的文字云创意赋能 !
图像处理·人工智能·macos·ios·信息可视化·iphone
关键帧Keyframe2 天前
音视频面试题集锦第 8 期
ios·音视频开发·客户端
pb82 天前
引入最新fluwx2.5.4的时候报错
flutter·ios