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 QtWidgets
except:
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()
也没有这种问题