6.线程
线程的概念:
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程实际的运作单位之一
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条进程并行不同的任务
创建线程
以函数形式创建多线程的方法
import threading 导入模块
t1=threading.Thread(target=函数名,args=(给函数的参数))#创建一个多进程对象
t1.start() 启动新建的进程对象,即开启新进程
t1.join() 该线程执行完毕后,才能执行该代码,在子程序完成运行前,这个子线程的父线程将一直被阻塞
threading.current_thread() 返回当前的线程名,在主线程就返回主线程,在子线程中就返回子线程+编号
threading.current_count() 返回当前存活的进程数
t1.setdaemon(True) 守护线程,一旦给某个子线程设置守护线程,只要主线程结束,就立即结束该子线程,没有设置守护进程的函数,依然继续执行
举例如下:
def a(): print('函数a执行') time.sleep(5) print('a函数结束') t1=threading.Thread(target=a) if __name__=="__main__": t1.setDaemon(True) #设置守护线程,注意一定要设置在start前 t1.start() print("主线程结束")
如上代码,只要主线程一结束,子线程也立即结束,线程守护使正在阻塞的子程序立即结束
类继承方式创建多线程
新建一个类,继承threading.Thread,
如果有参数,就重写该类的__init__方法
定义每个线程要运行的函数,函数名一定为run,因为这是父类要执行的方法
实例化对象
对象.start 即可启动新建的多线程
举例如下:
import threading import time class Hello(threading.Thread): def __init__(self,a): threading.Thread.__init__(self) #该代码固定,不可改变 self.a=a def run(self): #run方法没有执行,但是在新建的线程中依然执行了,这是因为父类方法一定调用执行了该run方法 print('线程开始%s'%self.a) time.sleep(3) print('线程结束%s'%self.a) if __name__=='__main__': print('主线程开始') hello=Hello(2) hello.start() time.sleep(2) print('主线程结束')
多线程时系统的运行方式:
IO密集型任务或函数:在程序中存在阻塞的情况
计算密集型任务函数:在程序运行时没有阻塞情况的代码
在Python中,多线程是cpu在运行是来回替换线程运行的,如果是IO密集型任务函数,cpu会在一个线程阻塞时执行另一个线程,使用多线程会节省程序的运行时间,如果是计算密集型函数,多线程就无法减少程序运行的总时间。反而会因为cpu的来回切换,增加cpu处理程序的时间,反而不如单线程执行.
结论:
在python里,如果任务是IO密集型的,可以用多线程;如果是计算密集型,使用多线程没有帮助,无法减少代码执行时间
GIL
python的多线程中,即使电脑是多核,也只能调用一个cpu来执行多线程程序,这是因为python中的GIL
GIL:全局解释器锁,被加在解释器上,是cpython解释器中的独有问题
GIL的作用:在同一时刻,只能由一个线程进入解释器,所以多个线程只能来回切换进入解释器运行,解释器再调用cpu,因此python中实际上是没有多进程的
想让一端函数使用一个cpu,在python中,就只能使用多进程
在普通代码中,全程只有一个线程,代码从上到下依次进行
在多线程代码中,启动几个线程,程序就在原有的进程上添加几个线程,几个线程之间同时运行,线程之间可以互相影响,相互通信的.
如下是一个函数创建多线程的代码:
import threading import time def foo(c): start = time.time() time.sleep(3) print('foo%s结束' % c) end = time.time() print(end - start) def bar(c): start = time.time() time.sleep(5) #sleep时代码不运该进程行任何程序 print('bar%s结束' % c) end = time.time() print(end - start) if __name__=='__main__': t1=threading.Thread(target=foo,args=(1,)) #为函数foo()创建一个线程对象 t2=threading.Thread(target=bar,args=(2,)) #为函数bar()创建一个线程对象 start = time.time() t1.start() #启动线程t1 t2.start() #启动线程t2 end=time.time() print(end-start) print('结束')

浙公网安备 33010602011771号