weiqi7777

python的多线程与多进程

0
阅读(2579)

python使用threading库,可以实现多线程,使用multiprocessing库实现多进程。

一、多线程

python使用threading库来实现多线程。

threading自带的方法:

clip_image002

其中有一个方法,

enumerate():获取当前所有子线程,返回子线程的列表。

该列表,至少会有一个元素,就是主线程。

clip_image004

threading库下有Thread类,创建多线程。

对于Thread类,有如下的几个属性以及方法:

clip_image006

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)

通过threadingThread类,创建了5个类。target指定线程执行函数,args表示给线程传递的参数。

通过threading.emuerate()获取当前执行的线程。

th_list是线程列表,总共有7个线程,一个主线程,MainThread,一个守护进程,SockThread5个子线程,Thread-1 – Thread-5

clip_image008

左图是打印的线程的名字,右图是线程执行的打印信息。

对于线程,所有线程的PID都是一样的。

clip_image009clip_image010

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)

执行效果:

当前执行的所有线程。

clip_image012

左图是打印的线程的名字,右图是线程执行的打印信息。

对于线程,所有线程的PID都是一样的。

clip_image013clip_image014

二、多进程

python使用multiprocessing库来是实现多进程

clip_image016

multiprocessing库下有一个方法:

active_children()获取当前的所有子进程,返回子进程列表。

该列表,在没有子进程时,返回空列表。

clip_image017

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类,有如下一些属性和方法:

clip_image019

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下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。

对于进程列表,保存的是所有子进程的进程列表。

clip_image021

linux下执行,进程列表,进程名,进程执行结果都会打印。

对于不同的子进程,PID是不一样的。

clip_image023

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的名字。

clip_image025

linux下执行,进程列表,进程名,进程执行结果都会打印。

对于不同的子进程,PID是不一样的。

clip_image027

Baidu
map