关于openharmony线程安全函数的一些坑

最近工作中遇到一个场景,进入一个C接口后,里面会执行回调,原来的库是同步线程,回调一切正常。最近库更新了,接口内会创建一个线程去并发做一些工作来提高效率和体验,回调函数会被两个线程同时调用。

最初napi层和arkts层代码没有改动,运行直接cppcrash,由于跨了线程,内存申请直接崩。

改成线程安全函数来调用,结果发现回调"没有执行"。

自己写了个示例,发现回调可以触发,但原工程的就是不行。经过不停的追加日志跟踪,发现线程安全函数是在接口return后才开始执行的,而原工程在接口结束后,会结束掉调用线程来回收资源,作为一个18年的C/C++程序员,真的有点想爆粗口。

查了一下资料,官方的资料并不多,只是给了简单调用示例,后来从部分文字中看出,线程安全函数是把回调放入队列来执行,并发立即执行,这也是为什么回调在接口return之后才执行,因为接口是队列中正在执行的任务。

没办法,改逻辑,把回调放到专用线程里,保正线程不会停止,原接口内的各个线程,都不在调用本线程内的回调。

改过之后,逻辑是对的,但仍然会崩,而且必崩在接口结束后。观察了napi层所有变量的生命周期,没问题!那问题就出现在底层库了。底层库回调时会传一个指针,而这个指针在接口结束前会被释放。PC端回调是同步的,所以不会有任何问题,释放时不会有任何地方去使用这个地址,但harmony不行,回调是异步的,指针释放时,部分回调操作不能保正完成,而且,底层库和napi层也无法用锁或者其它方式同步。

最后,解决办法是把底层库的指针定义为全局,不释放也不多次申请空间。好处是避免了线程同步问题,缺点是常占内存资源。

总之,harmony回调时需要注意以下几点:

1、回调函数和调用者需要属于相同的线程,否则要使用线程安全函数,也许还有其它方法但没有明确的资料作为证据,本人也没发现,暂且这样说。

2、确保所有回调结束前,回调函数所在线程存在,并且调用回调的线程被允许调用回调函数。

3、确保回调中使用的指针地址不会在回调结束前释放,以及回调函数参数的生命周期不会在回调结束前结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿捏利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值