이 기사는 Python 다중 프로세스 제어에 대한 튜토리얼(예제 포함)을 제공합니다. 필요한 참고 자료가 있으면 도움이 될 것입니다.
멀티프로세싱 소개
멀티프로세싱은 대규모 배치로 프로세스를 생성할 수 있는 Python 고유의 다중 프로세스 모듈입니다. 서버에 스레딩 모듈과 유사한 멀티 코어 CPU가 있을 때 더 잘 작동합니다. 멀티스레딩에 비해 멀티프로세싱은 독점적인 메모리 공간으로 인해 더 안정적이고 안전합니다. 작업 및 유지 관리 시 일괄 작업을 수행할 때 멀티프로세싱 패키지는 로컬 및 유지 관리라는 두 가지 유형의 동시 작업을 제공합니다. 전역 해석 잠금이 있는 스레드 대신 하위 프로세스를 사용하지 않는 것이 효과적입니다. 따라서 다중 처리는 다중 코어 처리를 효과적으로 활용할 수 있습니다
Process 클래스다중 처리에서는 Process 클래스 객체를 통해 프로세스가 일괄 생성됩니다. , start() 메소드를 사용하여 이 프로세스를 시작합니다
1. Syntax
multiprocessing.Process(group=None,target=None,name=None,args=(),kwargs={},*)
group: 这个参数一般为空,它只是为了兼容threading.Tread
target: 这个参数就是通过run()可调用对象的方法,默认为空,表示没有方法被调用
name: 表示进程名
args: 传给target调用方法的tuple(元组)参数
kwargs: 传给target调用方法的dict(字典)参数
run()이 메소드는 프로세스의 실행 프로세스입니다. 이 메서드를 작성할 때 일반적으로 리팩토링되는 경우는 거의 없습니다
start()프로세스를 시작하려면 이 메서드로 각 프로세스 객체를 호출해야 합니다
join([timeout]) 프로세스가 종료될 때까지 기다린 다음 추가로 실행하면 시간 제한을 설정하여
name 프로세스 이름을 얻을 수 있으며, 여러 프로세스도 동일한 이름을 가질 수 있습니다.
반환 프로세스가 아직 살아 있는지 여부, True 또는 False, 프로세스 생존은 start()의 시작부터 하위 프로세스의 종료까지를 의미합니다. ()는 백그라운드 실행 여부를 나타냅니다참고: 백그라운드 실행이 설정되어 있으면 백그라운드 프로그램이 실행되지 않고 하위 프로세스가 생성됩니다
pid프로세스 ID를 얻을 수 있습니다
exitcode자식 프로세스가 종료되지 않은 경우 값은 None이 됩니다. 음수 값은 하위 프로세스가 종료됨을 의미합니다.
terminate()종료하려면 Windows인 경우, 종료 프로세스()를 사용하십시오. 종료되고 종료된 프로세스에 대해서는 이 메소드가 실행되지 않습니다
#-*- coding:utf8 -*-
import multiprocessing
import time
def work(x):
time.sleep(1)
print time.ctime(),'这是子进程[{0}]...'.format(x)
if __name__ == '__main__':
for i in range(5):
p = multiprocessing.Process(target=work,args=(i,))
print '启动进程数:{0}'.format(i)
p.start()
p.deamon = True
물론 각 프로세스의 ID는 다음과 같습니다. 프로세스도 표시할 수 있습니다
#-*- coding:utf8 -*- import multiprocessing import time import os def work(x): time.sleep(1) ppid = os.getppid() pid = os.getpid() print time.ctime(),'这是子进程[{0},父进程:{1},子进程:{2}]...'.format(x,ppid,pid) if __name__ == '__main__': for i in range(5): p = multiprocessing.Process(target=work,args=(i,)) print '启动进程数:{0}'.format(i) p.start() p.deamon = True
실제 사용 프로세스에서는 단순히 동시에 완료할 필요는 없습니다. 예를 들어 30개의 작업이 있는데 제한된 서버 리소스로 인해 매번 5개의 작업이 동시에 실행됩니다. 이는 또한 30개 작업을 어떻게 획득하느냐의 문제와도 관련되어 있으며, 동시 프로세스 작업, 특히 시간이 필요한 작업의 일관된 실행 시간을 보장하기 어렵고, 그 중 3개 작업이 동시에 실행될 수 있습니다. 후속 작업을 계속 실행하기 전에 이 두 프로세스가 실행될 때까지 기다릴 수 없습니다. 따라서 프로세스 제어에는 Process 메서드를 사용할 수 있으며 일부 다중 처리 패키지와 클래스가 조합되어 사용됩니다. 프로세스 제어 및 통신을 위한 공통 클래스
1. 대기열 클래스
는 Python에 포함된 Queue.Queue와 유사하며 주로 상대적으로 작은 대기열에 사용됩니다. 구문: multiprocessing.Queue([maxsize])
qsize ()대략적인 대기열 크기를 반환합니다. 여러 프로세스나 스레드가 대기열을 소비했기 때문에 데이터가 반드시 정확하지는 않기 때문입니다
empty()
대기열이 비어 있는지 확인하려면, 그렇다면 반환합니다. True, 그렇지 않으면 False
full()
put(obj[, block[, timeout]])
get()
#-*- coding:utf8 -*- from multiprocessing import Process, Queue def f(q): q.put([42,None,'hi']) if __name__ == '__main__': q = Queue() p = Process(target=f, args=(q,)) p.start() print q.get() #打印内容: [42,None,'hi'] p.join()
pipe() 함수는 한 쌍의 연결을 반환합니다. 프로세스 간에 메시지를 전송하는 경우 일부 로그 및 프로세스 제어를 인쇄하는 데 유용합니다. Pip() 개체는 두 개의 채널을 나타내는 두 개의 개체 연결을 반환합니다. 각 연결 개체에는 필요한 send() 및 recv() 메서드가 있습니다. 문제는 두 개 이상의 프로세스가 동시에 동일한 파이프를 읽거나 쓰므로 테스트 후 데이터 혼란이 발생할 수 있다는 것입니다. 또한 반환된 두 연결 중 하나가 send() 데이터인 경우 다른 연결은 recv()#-*- coding:utf8 -*-
from multiprocessing import Process, Pipe
import time
def f(conn,i):
print '[{0}]已经执行到子进程:{1}'.format(time.ctime(),i)
time.sleep(1)
w = "[{0}]hi,this is :{1}".format(time.ctime(),i)
conn.send(w)
conn.close()
if __name__ == '__main__':
reader = []
parent_conn, child_conn = Pipe()
for i in range(4):
p = Process(target=f, args=(child_conn,i))
p.start()
reader.append(parent_conn)
p.deamon=True
# 等待所有子进程跑完
time.sleep(3)
print '\n[{0}]下面打印child_conn向parent_conn传输的信息:'.format(time.ctime())
for i in reader:
print i.recv()
三、Value,Array
在进行并发编程时,应尽量避免使用共享状态,因为多进程同时修改数据会导致数据破坏。但如果确实需要在多进程间共享数据,multiprocessing也提供了方法Value、Array
from multiprocessing import Process, Value, Array def f(n, a): n.value = 3.1415927 for i in range(len(a)): a[i] = -a[i] if __name__ == '__main__': num = Value('d',0.0) arr = Array('i', range(10)) p = Process(target=f, args=(num, arr)) p.start() p.join() print num.value print arr[:]
*print
3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]*
四、Manager进程管理模块
Manager类管理进程使用得较多,它返回对象可以操控子进程,并且支持很多类型的操作,如: list, dict, Namespace、lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value, Array,因此使用Manager基本上就够了
from multiprocessing import Process, Manager def f(d, l): d[1] = '1' d['2'] = 2 d[0.25] = None l.reverse() if __name__ == '__main__': with Manager() as manager: d = manager.dict() l = manager.list(range(10)) p = Process(target=f, args=(d, l)) p.start() p.join() #等待进程结束后往下执行 print d,'\n',l
输出:
{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
可以看到,跟共享数据一样的效果,大部分管理进程的方法都集成到了Manager()模块了
五、对多进程控制的应用实例
#-*- coding:utf8 -*- from multiprocessing import Process, Queue import time def work(pname,q): time.sleep(1) print_some = "{0}|this is process: {1}".format(time.ctime(),pname) print print_some q.put(pname) if __name__ == '__main__': p_manag_num = 2 # 进程并发控制数量2 # 并发的进程名 q_process = ['process_1','process_2','process_3','process_4','process_5'] q_a = Queue() # 将进程名放入队列 q_b = Queue() # 将q_a的进程名放往q_b进程,由子进程完成 for i in q_process: q_a.put(i) p_list = [] # 完成的进程队列 while not q_a.empty(): if len(p_list) <p>执行结果:</p><p><img src="https://img.php.cn//upload/image/167/872/710/1542261551928622.png" title="1542261551928622.png" alt="Python 다중 프로세스 제어에 대한 튜토리얼 설명(예제 포함)"></p>
위 내용은 Python 다중 프로세스 제어에 대한 튜토리얼 설명(예제 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!