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. 函数实现
import threading import time import os
def say_hello(): pid = os.getpid() for i in range(5): print( str(pid) + ': ' + str(i) + '\n' ) time.sleep(2)
for i in range(5): th = threading.Thread(target=say_hello,args=()) th.start()
th_list = threading.enumerate() print (th_list)
for a in th_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__方法。
import threading import time import os
class say_hello(threading.Thread): def __init__(self): threading.Thread.__init__(self)
def run(self): pid = os.getpid() for i in range(5): print( str(pid) + ': ' + str(i) + '\n' ) time.sleep(2)
for i in range(5): th = say_hello() th.start()
th_list = threading.enumerate() print (th_list)
for a in th_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函数。
import multiprocessing import time import os
def say_hello(): pid = os.getpid() print ("child") for i in range(5): print( str(pid) + ': ' + str(i) + '\n' ) time.sleep(2)
for i in range(5): pr = multiprocessing.Process(target=say_hello,args=()) pr.start()
pr_list = multiprocessing.active_children() print (pr_list)
for a in pr_list: print(a.name) time.sleep(20) |
在window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。
对于进程列表,保存的是所有子进程的进程列表。
在linux下执行,进程列表,进程名,进程执行结果都会打印。
对于不同的子进程,PID是不一样的。
2. 类实现
将子线程,实现在类中,该类,继承multiprocessing.Process类。并且重载run方法,这样当调用类的start方法后,会自动调用run方法。
注意在__init__方法中,要执行父进程的__init__方法。
import multiprocessing import time import os
class say_hello(multiprocessing.Process): def __init__(self): multiprocessing.Process.__init__(self)
def run(self): pid = os.getpid() print ("child") for i in range(5): print( str(pid) + ': ' + str(i) + '\n' ) time.sleep(2)
for i in range(5): pr = say_hello() pr.start()
pr_list = multiprocessing.active_children() print (pr_list)
for a in pr_list: print(a.name) time.sleep(20) |
在window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。
对于进程列表,保存的是所有子进程的进程列表。进程的名字,默认为是class的名字。
在linux下执行,进程列表,进程名,进程执行结果都会打印。
对于不同的子进程,PID是不一样的。