Admin
起因是这样的,需要实现一个剪贴板监控程序,实时检剪贴板文本变更。使用的是库是 clipboard、pyperclip,在一个死循环内检测变更并做一些其他操作,在 windows 和 macos 上都能在一个线程内完成要求,但是 linux 环境下,访问剪贴板依赖 qt,需要运行 QApplication,故使用额外线程运行这个死循环:
def run_linux():@thread_function()@try_except('run client thread')def run_client_thread():run_client()try:from PyQt5 import QtWidgetsexcept:raise Exception(f'"pyqt5" not installed, which is required in linux system')run_client_thread()app = QtWidgets.QApplication(sys.argv)app.exec()def run_client():while 1:client = ClipClient()client.run()logger.debug('end')time.sleep(1)if __name__ == '__main__':if os.name in ('posix',):run_linux()else:run_client()
说明:
thread_function: 表示这个方法由另个线程执行try_except: 异常捕捉处理client.run(): 在内部阻塞处理一些逻辑(检测剪贴板,发送到远程 websocket),异常由内部捕获处理当 client.run() 阻塞时间很短(网络连接失败等)时, 在 pycharm 中 debug 一切正常, 一旦 run 就循环一次就进程退出 Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
按逻辑上说,循环体结尾有 time.sleep(1) 等待1秒,也不会大量占用资源。
但是,将 time.sleep(1) 移动到循环体首部就不会有任何问题:
def run_client():while 1:time.sleep(1)client = ClipClient()client.run()logger.debug('end')
在 windows 和 macos 平台,没有这种问题
在 linux 平台, 直接 run_client() 也没有这种问题