Admin

pyqt 死循环中time.sleep在循环体起始和末尾的差异
2019年6月6日 10:17 8 0 0 0

起因是这样的,需要实现一个剪贴板监控程序,实时检剪贴板文本变更。使用的是库是 clipboardpyperclip,在一个死循环内检测变更并做一些其他操作,在 windowsmacos 上都能在一个线程内完成要求,但是 linux 环境下,访问剪贴板依赖 qt,需要运行 QApplication,故使用额外线程运行这个死循环:

  1. def run_linux():
  2. @thread_function()
  3. @try_except('run client thread')
  4. def run_client_thread():
  5. run_client()
  6. try:
  7. from PyQt5 import QtWidgets
  8. except:
  9. raise Exception(f'"pyqt5" not installed, which is required in linux system')
  10. run_client_thread()
  11. app = QtWidgets.QApplication(sys.argv)
  12. app.exec()
  13. def run_client():
  14. while 1:
  15. client = ClipClient()
  16. client.run()
  17. logger.debug('end')
  18. time.sleep(1)
  19. if __name__ == '__main__':
  20. if os.name in ('posix',):
  21. run_linux()
  22. else:
  23. run_client()

说明:

  1. thread_function: 表示这个方法由另个线程执行
  2. try_except: 异常捕捉处理
  3. client.run(): 在内部阻塞处理一些逻辑(检测剪贴板,发送到远程 websocket),异常由内部捕获处理

client.run() 阻塞时间很短(网络连接失败等)时, 在 pycharmdebug 一切正常, 一旦 run 就循环一次就进程退出 Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

按逻辑上说,循环体结尾有 time.sleep(1) 等待1秒,也不会大量占用资源。

但是,将 time.sleep(1) 移动到循环体首部就不会有任何问题:

  1. def run_client():
  2. while 1:
  3. time.sleep(1)
  4. client = ClipClient()
  5. client.run()
  6. logger.debug('end')

windowsmacos 平台,没有这种问题
linux 平台, 直接 run_client() 也没有这种问题

发布内容,请遵守相关法律法规。
评论