【Python】高级培训多线程学习
多线程
多线程类似于同时执行多个不同程序,多线程运行有如下优点:
1.使用线程可以把占据长时间的程序中的任务放到后台去处理。
2.用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
3.程序的运行速度可能加快。
4.在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
创建线程
一个进程里面必然有一个主线程。
Python3 线程中常用的两个模块为:
- _thread
- threading(推荐使用)
thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。
Python中使用线程有两种方式:函数或者用类来包装线程对象。
函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:
_thread.start_new_thread ( function, args[, kwargs] )
参数说明:
1.function - 线程函数。
2.args - 传递给线程函数的参数,他必须是个tuple类型。
3.kwargs - 可选参数。
- 创建线程的两种方法
1.继承Thread类,并重写它的run()方法
import threading
import time
cLass MyThread(threading.Thread):
def__ init__ (seLf, n):
super (MyThread, seLf).__ init__()
self.n = n
def run(self):
print('以类的方式创建多线程',self.n)
time.sleep(3)
r1 = MyThread(1)
r2 = MyThread(2)
r1.start()
r2.start()
2.调用threading库的Thread类
import threading
import time
def test(x):
print(x)
time.sleep(2)
if __name__=='__main__':
t1 = threading.Thread(target=test, args=(1,))
t2 = threading.Thread(target=test, args=(2,))
t1.start()
t2.start()
-
线程模块
Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。
_thread 提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading 模块的功能还是比较有限的。
threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
isAlive(): 返回线程是否活动的。
getName(): 返回线程名。
setName(): 设置线程名。
-
守护线程
此类线程的特点是,当程序中主线程及所有非守护线程执行结束时,未执行完毕的守护线程也会随之消亡(进行死亡状态),程序将结束运行。
import threading
import time
def run(n):
print('task',n)
time.sleep(1)
print('3s')
time.sleep(1)
print('2s')
time.sleep(1)
print('1s')
if __name__ == '__main__': #主线程
t=threading.Thread(target=run,args=('t1',))
t.setDaemon(True) #设置子线程为守护线程,守护主线程。主线程结束,子线程也立马结束。必须在start() 方法调用之前设置
t.start()
print('end')
实例
在一个线程中,每秒循环输出当前的年月日时分秒
于此同时,在另一个线程中,实现张三的姓名每2秒打印输出4次结束。
注意:都需要使用类和继承实现功能
import datetime
import threading
import time
class myThread1(threading.Thread): # 继承父类threading.Thread
def run(self):
while True:
# 打印按指定格式排版的时间
time2 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(time2)
time.sleep(1) # 暂停1秒
class myThread2(threading.Thread): # 继承父类threading.Thread
def __init__(self, name):
super(myThread2, self).__init__()
self.name = name
def run(self):
for i in range(4): # 实现张三的姓名每2秒打印输出4次结束
print(self.name)
time.sleep(2) # 暂停2秒
if __name__ == '__main__':
m1 = myThread1()
m2 = myThread2("张三")
m2.start()
m1.start()