Linux的time命令运行原理是什么?是否和多线程相关?单线程OpenCV调用time报错
问题解答
1. Linux time命令的工作逻辑,和多线程的关联
time命令本身不会为被运行的程序创建额外的多线程运行环境。
time命令在Linux下有两种常见实现:
- Shell内置的time关键字:仅在当前shell进程内统计目标程序启动和终止的时间差,完全不干预目标程序的运行逻辑
- 外部的
/usr/bin/time工具:通过fork()+exec()启动目标程序,用wait()系列系统调用监听进程状态,统计用户态、内核态运行时间,也不会修改目标程序的线程结构、运行环境。
你遇到的多线程相关冲突和time本身无关,冲突来自OpenCV底层的隐式线程逻辑。
2. 报错原因分析
你遇到的BadAccess报错是X Window服务返回的资源访问错误,对应MIT-SHM(X共享内存扩展)的资源访问冲突,和上层代码有没有主动写多线程没有直接关系:
- OpenCV的
cv::imshow底层依赖GTK/Qt等UI后端,即使上层没有主动创建多线程,HighGUI模块内部本身会启动独立线程处理UI渲染、X服务交互逻辑,所以你调研到的多线程冲突场景是成立的,冲突发生在OpenCV底层的内部线程。 - 不使用time运行时,程序的IO、CPU调度时序是稳定的,
imshow和waitKey(1)的调用频率刚好适配底层UI线程和X服务的交互节奏,不会出现资源竞争。 - 用time运行时,time对进程的时间片统计、系统调用追踪会产生非常轻微的额外开销,刚好改变了原有代码的执行时序:
imshow的调用频率太快,waitKey(1)只等待1ms就直接进入下一轮循环,上一轮的共享内存资源还没被X服务释放,新一轮又申请同类型资源,就触发了X服务的BadAccess错误。 - 把
waitKey(1)改成无参的waitKey()后,每次调用都会阻塞等待用户输入,给了底层UI线程足够的时间完成和X服务的交互、释放共享内存资源,自然不会出现冲突。
3. 修复方案
任选一种即可解决问题:
- 把
waitKey(1)的等待时长适当调大,比如改成waitKey(5)或者更长,给底层UI交互留足够的处理时间 - 运行时禁用X的MIT-SHM扩展,执行命令前加对应环境变量:如果OpenCV用的Qt后端则执行
export QT_X11_NO_MITSHM=1,如果是GTK后端则执行export GDK_DISABLE_X11_SHM=1,再用time运行程序就不会触发共享内存冲突 - 不需要可视化时直接注释掉
imshow和waitKey相关代码,统计出来的运行时间也会更准确
内容的提问来源于stack exchange,提问作者KansaiRobot
相关产品推荐
相关产品推荐

