守护线程(Daemon Thread)

Java中有两类线程:用户线程(User Thread)、守护线程(Daemon Thread)
守护线程是在 程序运行的时候在后台提供通用服务的线程,比如垃圾回收线程。当所有的非守护线程结束时,程序会终止并杀死进程中的所有守护线程。反过来,只要有非守护线程在运行,程序就不会终止。

  • thread.setDaemon(true)必须在thread.start()之前设置,即不能把一个正在运行的常规线程设置为守护线程。
  • 在Daemon线程中产生的新线程也是Daemon线程。
  • 守护线程不应该去访问固有资源,因为它会在任何时候退出。

多线程

程序中有多个线程时,主线程结束并不会影响子线程继续执行,即只有当程序中所有线程全执行完毕后,程序才真正结束。

import threading

#主线程执行如下语句
for i in range(5):
    print(threading.current_thread().getName())

#定义线程要调用的方法,*add可接收多个以非关键字方式传入的参数
def action(*add):
    for arc in add:
        #调用 getName() 方法获取当前执行该程序的线程名
        print(threading.current_thread().getName() +" "+ arc)
#定义为线程方法传入的参数
my_tuple = ("http://c.biancheng.net/python/",\
            "http://c.biancheng.net/shell/",\
            "http://c.biancheng.net/java/")
#创建线程
thread = threading.Thread(target = action,args =my_tuple)
#启动线程
thread.start()

程序执行结果:

MainThread
MainThread
MainThread
MainThread
MainThread
Thread-1 http://c.biancheng.net/python/
Thread-1 http://c.biancheng.net/shell/
Thread-1 http://c.biancheng.net/java/

创建守护线程

import threading
#定义线程要调用的方法,*add可接收多个以非关键字方式传入的参数
def action(length):
    for arc in range(length):
        #调用 getName() 方法获取当前执行该程序的线程名
        print(threading.current_thread().getName()+" "+str(arc))
#创建线程
thread = threading.Thread(target = action,args =(20,))
#将thread设置为守护线程
thread.daemon = True
#启动线程
thread.start()
#主线程执行如下语句
for i in range(5):
    print(threading.current_thread().getName())

执行结果:

Thread-1 0
MainThread
MainThread
Thread-1 1
MainThread
Thread-1 2
MainThread
MainThread

主线程与其他非守护线程结束后,程序结束。

QThread Qt中的线程类

定义一个工作类,在工作类中发送信号,槽为主线程中的函数,即在主线程中执行更新界面操作

class WorkThread(QThread):
    timer = pyqtSignal()   # 每隔1秒发送一次信号
    end = pyqtSignal()     # 计数完成后发送一次信号
    def run(self):
        while True:
            self.sleep(1)  # 休眠1秒
            if sec == 5:
                self.end.emit()   # 发送end信号
                break
            self.timer.emit()   # 发送timer信号

class Counter(QWidget):
    def __init__(self, parent=None):
        super(Counter, self).__init__(parent)

        self.setWindowTitle("使用线程类(QThread)编写计数器")
        self.resize(300, 120)

        layout = QVBoxLayout()
        self.lcdNumber = QLCDNumber()
        layout.addWidget(self.lcdNumber)

        button = QPushButton('开始计数')
        layout.addWidget(button)

        self.workThread = WorkThread()

        self.workThread.timer.connect(self.countTime)
        self.workThread.end.connect(self.end)
        button.clicked.connect(self.work)

        self.setLayout(layout)

    def countTime(self):
        global sec
        sec += 1
        self.lcdNumber.display(sec)

    def end(self):
        QMessageBox.information(self,'消息','计数结束',QMessageBox.Ok)

    def work(self):
        self.workThread.start()