python的多线程与多进程
0赞python使用threading库,可以实现多线程,使用multiprocessing库实现多进程。
一、多线程
python使用threading库来实现多线程。
threading自带的方法:
其中有一个方法,
enumerate():获取当前所有子线程,返回子线程的列表。
该列表,至少会有一个元素,就是主线程。
threading库下有Thread类,创建多线程。
对于Thread类,有如下的几个属性以及方法:
name |
线程的名字 |
setDaemon() |
设置线程是否是deamon线程,传参为True或者False,默认是False。如果线程是守护线程,那么进程结束后,该线程也会被结束。 |
getName() |
获取线程的名字 |
setName() |
设置线程的名字 |
is_alive() |
线程是否有效 |
join([timeout]) |
该方法会将主调线程阻塞,知道该线程执行完毕后,主线程才会执行。timeout是一个超时时间。 |
start() |
启动线程 |
run() |
线程启动之后执行的函数,可以重载该函数 |
多线程,有两种方法实现,一种是用函数,一种是用类。
1.函数实现
importthreading importtime importos defsay_hello(): pid=os.getpid() foriinrange(5): print(str(pid)+': '+str(i)+'\n') time.sleep(2) foriinrange(5): th=threading.Thread(target=say_hello,args=()) th.start() th_list=threading.enumerate() print(th_list) forainth_list: print(a.name) time.sleep(20) |
通过threading的Thread类,创建了5个类。target指定线程执行函数,args表示给线程传递的参数。
通过threading.emuerate()获取当前执行的线程。
th_list是线程列表,总共有7个线程,一个主线程,MainThread,一个守护进程,SockThread,5个子线程,Thread-1 – Thread-5。
左图是打印的线程的名字,右图是线程执行的打印信息。
对于线程,所有线程的PID都是一样的。
2.类实现
将子线程,实现在类中,该类,继承threading.Thread类。并且重载run方法,这样当调用类的start方法后,会自动调用run方法。
注意在__init__方法中,要执行父进程的__init__方法。
importthreading importtime importos classsay_hello(threading.Thread): def__init__(self): threading.Thread.__init__(self) defrun(self): pid=os.getpid() foriinrange(5): print(str(pid)+': '+str(i)+'\n') time.sleep(2) foriinrange(5): th=say_hello() th.start() th_list=threading.enumerate() print(th_list) forainth_list: print(a.name) time.sleep(20) |
执行效果:
当前执行的所有线程。
左图是打印的线程的名字,右图是线程执行的打印信息。
对于线程,所有线程的PID都是一样的。
二、多进程
python使用multiprocessing库来是实现多进程
multiprocessing库下有一个方法:
active_children():获取当前的所有子进程,返回子进程列表。
该列表,在没有子进程时,返回空列表。
Queue类,实现进程间的数据传递通信。一个Queue可以连接多个进程。比如可以将父进程和所有的子进程,用Queue进行连接,实现父子进程之间的通信。Queue的大小可以无限大,在例化Queue的时候指定。
如Queue(5),指定Queue的大小为5
Queue(),Queue无限大
Queue在多线程之间,也可以用于通信。
Queue有三个常用方法:
empty() |
Queue是否空,即是否有数据在Queue中。 |
put(data, block=, timeout= ) |
将data放入到Queue中,block有两个选项,True表示如果put不成功,就阻塞。False表示即使put不成功,也不会阻塞。timeout指阻塞的最大时间。 |
get(block=,timeout) |
从Queue中获取数据。返回获取的数据。block有两个选项,True表示如果get不成功,就阻塞。False表示即使get不成功,也不会阻塞。timeout指阻塞的最大时间。 |
multiprocessing库下有Process类,创建子进程。
对于Process类,有如下一些属性和方法:
name |
进程的名字 |
pid |
进程的pid |
daemon |
进程是否是守护进程,True或者False。如果是守护进程,主进程结束之后,守护进程将会被结束 |
is_alive() |
进程是否有效 |
start() |
启动子进程 |
run() |
子进程启动之后执行的方法,可以重载该方法 |
terminater() |
终止该进程 |
join(timeout) |
阻塞父进程,直到子进程执行完毕后,父进程才可执行。timeout指定最多阻塞父进程的时间 |
多进程,有两种方法实现,一种是用函数,一种是用类。
1.函数实现
使用multiprocessing下的Process类,创建一个对象,传入target参数为say_hello函数。调用对象的start方法,该方法会自动调用传入的say_hello函数。
importmultiprocessing importtime importos defsay_hello(): pid=os.getpid() print("child") foriinrange(5): print(str(pid)+': '+str(i)+'\n') time.sleep(2) foriinrange(5): pr=multiprocessing.Process(target=say_hello,args=()) pr.start() pr_list=multiprocessing.active_children() print(pr_list) forainpr_list: print(a.name) time.sleep(20) |
在window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。
对于进程列表,保存的是所有子进程的进程列表。
在linux下执行,进程列表,进程名,进程执行结果都会打印。
对于不同的子进程,PID是不一样的。
2.类实现
将子线程,实现在类中,该类,继承multiprocessing.Process类。并且重载run方法,这样当调用类的start方法后,会自动调用run方法。
注意在__init__方法中,要执行父进程的__init__方法。
importmultiprocessing importtime importos classsay_hello(multiprocessing.Process): def__init__(self): multiprocessing.Process.__init__(self) defrun(self): pid=os.getpid() print("child") foriinrange(5): print(str(pid)+': '+str(i)+'\n') time.sleep(2) foriinrange(5): pr=say_hello() pr.start() pr_list=multiprocessing.active_children() print(pr_list) forainpr_list: print(a.name) time.sleep(20) |
在window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。
对于进程列表,保存的是所有子进程的进程列表。进程的名字,默认为是class的名字。
在linux下执行,进程列表,进程名,进程执行结果都会打印。
对于不同的子进程,PID是不一样的。