线程装饰函数-is_alive属性

问题描述 投票:0回答:1

TLDR:当我使用线程函数作为另一个函数的装饰器时,如何检查线程是否还活着?

我正在使用 PyQt6 创建一个 GUI(如果选择不好,将接受其他建议)。 我的问题是当我单击“连接”按钮时,我想验证连接线程是否未运行。

由于代码太长,我用 ** 标记了相关内容

所以我在主init中创建了self.ecMaster属性,我尝试使用用@threaded装饰的is_alive方法来检查ecConnection是否已启动。

我收到错误:AttributeError:“function”对象没有属性“is_alive”

我应该怎样做才正确? 谢谢你

主要

from threading import thread
import pysoem
import ecAPI as ec
from PyQt6.QtWidgets import *
from PyQt6.QtCore import *
from PyQt6.QtGui import *

class mainWindow(QMainWindow):
    exitSignal = Signal()  # Define the custom exit signal

    def __init__(self,*args, **kwargs):        
        super().__init__(*args, **kwargs)
        self.exitSignal.connect(app.quit)
        self.central_widget = QWidget(self)
        self.test_widget = QWidget(self)
        self.modeSignal = ''
        self.operatorSignal = ''
        self.setCentralWidget(self.central_widget)
        self.connectionWindowLayout()
        **self.master = ec.ecMaster()**

def connectButtonClicked(self):
    self.connect_button.clickable = False
    # here i ran into trouble
    **if self.master.ecConnection.is_alive:**              # If thread is active
        self.master.ecConnection.terminate()
        logger.info('Connection thread was already active, terminated')
    logger.info('Starting connection thread')
    **self.master.ecConnection()**                      # Start connection thread
    time.sleep(0.1)  

if __name__ == '__main__':
    
    logger = logging.getLogger(__name__)
    logging.getLogger().setLevel(logging.INFO)
    
    app = QApplication(sys.argv)
    ModernStyle.apply(app)
    window = mainWindow()
    window.show()
    sys.exit(app.exec())

ecAPI.py

import pysoem, logging
from threading import Thread

def threaded(fn):
    # To use as decorator to make a function call threaded 
    def wrapper(*args, **kwargs):
        thread = Thread(target=fn, args=args, kwargs=kwargs)
        thread.start()
        return thread
    return wrapper

class ecMaster(pysoem.Master):
    def __init__(self):
        self.connectionSignal = 0
        super().__init__()
    
    def findAdapters(self):
        nicName = 'PCIe'            # Change based on PC --- 'PCIe
        network_adapters = pysoem.find_adapters()
        for adapter in network_adapters:
            if nicName in str(adapter[1]):
                networkAdapterID = adapter[0]
                self.open(networkAdapterID)
                logging.info('Found network adapter\n'+str(networkAdapterID))
        return len(network_adapters)>0 # True if found

    @threaded
    def ecConnection(self):
        if self.findAdapters():
            print('Searching for EC devices ... ')
            self.connectionSignal = self.config_init()         # Initilize connection
            if self.slaves:
                print(f'Found {len(self.slave_list)} devices')
                for i,slave in enumerate(self.slaves):
                    # ven = slave.sdo_read(0x1018, 1)
                    print(f'Found Device {slave.name},{slave.id},{slave.man}') #,{slave.sdo_read()}
                    logging.info(f'Found {self.connectionSignal} EC devices')
            else: 
                logging.info('No salves were found')
                print('Slaves not found')
        else:
            logging.warning('No network adapter found')
            print('No network adapter found')

尝试去掉包装纸并只留下线。 网上搜了一下。 期望我装饰的函数具有 Thread 属性,但无法正确实现。

python python-3.x multithreading python-multithreading ethercat
1个回答
0
投票

找到了解决办法。

self.master.ecConnection()
不是线程而是函数。仅当运行它时,它才成为一个线程(由于
@threaded
装饰器)。 因此我添加了
con_thread = self.master.ecConnection()
然后 con_thread 确实是一个线程对象,我可以访问
con_thread.is_alive()

© www.soinside.com 2019 - 2024. All rights reserved.