python并发编程-------线程
1.线程
进程multiprocess模块基本模仿了线程threading模块的接口。两者在使用层面基本类似。
线程的好处:
(1).创建进程的速度要比进程快
(2)同一进程内的线程,内存空间是共享的。
2.线程开启的两种方式:
#开启线程的方式一:跟开启进程的方式类似,使用替换threading模块提供的Thread from threading import Thread def task(): print('is running') if __name__ == '__main__': t=Thread(target=task,) t.start() print('主') #结果是先打印'is running'在打印'主',因为创建线程的速度快 #开启线程的方式二:自定义类,继承Thread from threading import Thread class MyThread(Thread): def __init__(self,name): super().__init__() self.name=name def run(self): print('%s is running' %self.name) if __name__ == '__main__': t=MyThread('test') t.start() print('主')
3.在主进程下开启多个线程,每个线程的pid跟主进程的pid一样
from threading import Thread import os def task(): print('%s is running' %os.getpid()) #获取线程的pid if __name__ == '__main__': t1=Thread(target=task,) t2=Thread(target=task,) t1.start() t2.start() print('主',os.getpid()) #获取主线程的pid
结果:
4.同一进程内的线程共享该进程的数据
from threading import Thread n=100 def work(): global n #将下面的n定义成全局参数 n=0 if __name__ == '__main__': t=Thread(target=work,) t.start() t.join() #主进程等待线程执行完在执行 print('主',n) #查看结果为0,因为同一进程内的线程之间共享进程内的数据
5.Thread模块的其他用法
Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
代码:
from threading import Thread,activeCount,enumerate,current_thread import time def task(): print('%s is running' %current_thread().getName()) #current_thread 获取线程的名称。 time.sleep(2) if __name__ == '__main__': t=Thread(target=task,) t.start() t.join() print(t.is_alive()) #判断线程是否存活 print(t.getName()) #获取线程的名称 print(enumerate()) #返回一个包含正在运行的线程的列表 print('主') print(activeCount()) #获取正在运行的线程数量
6.守护线程
无论是守护进程还是守护线程,都是遵循,守护xxx会等待主xxx运行完毕后被销毁。
注意:运行完毕并非终止运行。
(1)对于主进程来说,运行完毕是指主进程代码运行完毕
(2)对于主线程来说,运行完毕是指主线程所在的进程内所有非守护线程均运行完毕,主线程才算运行完毕。
详细解释:
#1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束, #2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
具体代码:
from threading import Thread import time def task1(): print('123') time.sleep(10) print('123done') def task2(): print('456') time.sleep(1) print('456done') if __name__ == '__main__': t1=Thread(target=task1) t2=Thread(target=task2) t1.daemon=True #跟守护进程一样 必须在start之前设置 t1.start() t2.start() print('主')
执行结果: