守护线程(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()