即进程控制块。
进程要完成哪些功能以及如何完成;2,数据集则是程序在执行过程中所需要的资源;3,进程控制块用来记录进程的外部特征,描述进程
的执行变化过程,系统可以用它来控制管理进程。
进程:操作系统资源分配的最小单位,程序隔离的边界,即一个程序运行起来后,代码+用到的资源。
进程的状态:新建,就绪,运行,等待,死亡
就绪态:运行的条件都已经满足,正在等待cpu执行
执行态:cpu正在执行其功能
等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态
创建子进程
P1 = mutiprocessing.Process()
P1.start()
创建子进程跟创建线程十分类似,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动
进程名称获取
mutiprocessing.current_process()
进程pid
1)mutiprocessing.current_process().pid
2) 使用import
os模块的getpid()/getppid()
进程间不共享全局变量
守护主进程
1) p1.daemon = True 设置守护主进程
2) p1.terminate() 强制退出整个程序
进程间通信Queue
queue = mutiprocessing.Queue(3) 定义消息队列
queue.qsize() 返回当前队列中包含的消息数量
queue.empty() 如果队列为空则返回True,其他返回False
queue.full() 如果队列为满则返回True,其他返回False
进程的创建
from multiprocessing import Process ''' 直接从侧面用subprocesses替换线程使用GIL的方式, 由于这一点,multiprocessing模块可以让程序员在给定的机器上充分的利用CPU。 在multiprocessing中,通过创建Process对象生成进程,然后调用它的start()方法, ''' def work(name): print('in work', name) p = Process(target=work, args=('jack',)) # 使用mutiprocessing.Process(target=, args=, name=)创建子进程 p.start() # 启动子进程 p.join() # 让主程序等待子进程执行结束
进程间的通信(全局变量)
# # import multiprocessing # (数值型) # # # def func(num): # num.value = 10.78 # 子进程改变数值的值,主进程跟着改变 # # # if __name__ == "__main__": # num = multiprocessing.Value("d", 10.0) # d表示数值,主进程与子进程共享这个value。(主进程与子进程都是用的同一个value) # # print(num.value) # 输出结果为10.0 # # p = multiprocessing.Process(target=func, args=(num,)) # # p.start() # # p.join() # # print(num.value) # 输出结果为10.78 # import multiprocessing # (数组型) # # # def func(num): # num[2] = 9999 # 子进程改变数组,主进程跟着改变 # # # if __name__ == "__main__": # num = multiprocessing.Array("i", [1, 2, 3, 4, 5]) # 主进程与子进程共享这个数组 # # print(num[:]) # 运行结果 [1, 2, 3, 4, 5] # # p = multiprocessing.Process(target=func, args=(num,)) # # p.start() # # p.join() # # print(num[:]) # 运行结果 [1, 2, 9999, 4, 5] # # import multiprocessing # (dict, list) # # # def func(mydict, mylist): # mydict["index1"] = "aaaaaa" # 子进程改变dict,主进程跟着改变 # # mydict["index2"] = "bbbbbb" # # mylist.append(11) # 子进程改变List,主进程跟着改变 # # mylist.append(22) # # mylist.append(33) # # # if __name__ == "__main__": # with multiprocessing.Manager() as MG: # 重命名 # # mydict = multiprocessing.Manager().dict() # 主进程与子进程共享这个字典 # # mylist = multiprocessing.Manager().list(range(5)) # 主进程与子进程共享这个List # # p = multiprocessing.Process(target=func, args=(mydict, mylist)) # # p.start() # # p.join() # # print(mylist) # 运行结果[0, 1, 2, 3, 4, 11, 22, 33] # # # print(mydict) ## 运行结果{'index1': 'aaaaaa', 'index2': 'bbbbbb'} # from multiprocessing import Array,Value,Process # ''' # 数据可以用Value或Array存储在一个共享内存地图里, # 创建num和arr时,“d”和“i”参数由Array模块使用的typecodes创建: # “d”表示一个双精度的浮点数,“i”表示一个有符号的整数,这些共享对象将被线程安全的处理 # ''' # def func(a,b): # a.value = 3.333333333333333 # for i in range(len(b)): # b[i] = -b[i] # # # if __name__ == "__main__": # num = Value('d',0.0) # arr = Array('i',range(11)) # # # c = Process(target=func,args=(num,arr)) # d= Process(target=func,args=(num,arr)) # c.start() # d.start() # c.join() # d.join() # # print(num.value) # 输出结果为3.333333333333333 # print(arr) # 输出结果为<SynchronizedArray wrapper for <multiprocessing.sharedctypes.c_int_Array_11 object at 0x7fb509623620>> # for i in arr: # print(i) # 输出结果为0 # # 1 # # 2 # # 3 # # 4 # # 5 # # 6 # # 7 # # 8 # # 9 # # 10 from multiprocessing import Process,Manager ''' 由Manager()返回的manager提供list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array类型的支持。 Server process manager比 shared memory 更灵活,因为它可以支持任意的对象类型。另外, 一个单独的manager可以通过进程在网络上不同的计算机之间共享,不过他比shared memory要慢。 ''' def f(d,l): d["name"] = "zhangyanlin" d["age"] = 18 d["Job"] = "pythoner" l.reverse() if __name__ == "__main__": with Manager() as man: d = man.dict() l = man.list(range(10)) p = Process(target=f,args=(d,l)) p.start() p.join() print(d) # 输出结果{'Job': 'pythoner', 'name': 'zhangyanlin', 'age': 18} print(l) # 输出结果[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
进程池
#apply from multiprocessing import Pool import time def f1(i): time.sleep(0.5) print(i) return i + 100 if __name__ == "__main__": pool = Pool(5) for i in range(1,31): pool.apply(func=f1,args=(i,)) #apply_async def f1(i): time.sleep(0.5) print(i) return i + 100 def f2(arg): print(arg) if __name__ == "__main__": pool = Pool(5) for i in range(1,31): pool.apply_async(func=f1,args=(i,),callback=f2) pool.close() pool.join()
Pool类描述了一个工作进程池,他有几种不同的方法让任务卸载工作进程。
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
我们可以用Pool类创建一个进程池, 展开提交的任务给进程池。
一个进程池对象可以控制工作进程池的哪些工作可以被提交,它支持超时和回调的异步结果,有一个类似map的实现。
- processes :使用的工作进程的数量,如果processes是None那么使用 os.cpu_count()返回的数量。
- initializer: 如果initializer是None,那么每一个工作进程在开始的时候会调用initializer(*initargs)。
- maxtasksperchild:工作进程退出之前可以完成的任务数,完成后用一个心的工作进程来替代原进程,来让闲置的资源被释放。maxtasksperchild默认是None,意味着只要Pool存在工作进程就会一直存活。
- context: 用在制定工作进程启动时的上下文,一般使用 multiprocessing.Pool() 或者一个context对象的Pool()方法来创建一个池,两种方法都适当的设置了context
注意:Pool对象的方法只可以被创建pool的进程所调用。
New in version 3.2: maxtasksperchild
New in version 3.4: context
进程池的方法
-
apply(func[, args[, kwds]]) :使用arg和kwds参数调用func函数,结果返回前会一直阻塞,由于这个原因,apply_async()更适合并发执行,另外,func函数仅被pool中的一个进程运行。
-
apply_async(func[, args[, kwds[, callback[, error_callback]]]]) : apply()方法的一个变体,会返回一个结果对象。如果callback被指定,那么callback可以接收一个参数然后被调用,当结果准备好回调时会调用callback,调用失败时,则用error_callback替换callback。 Callbacks应被立即完成,否则处理结果的线程会被阻塞。
-
close() : 阻止更多的任务提交到pool,待任务完成后,工作进程会退出。
-
terminate() : 不管任务是否完成,立即停止工作进程。在对pool对象进程垃圾回收的时候,会立即调用terminate()。
-
join() : wait工作线程的退出,在调用join()前,必须调用close() or terminate()。这样是因为被终止的进程需要被父进程调用wait(join等价与wait),否则进程会成为僵尸进程。
-
map(func, iterable[, chunksize])¶
-
map_async(func, iterable[, chunksize[, callback[, error_callback]]])¶
-
imap(func, iterable[, chunksize])¶
-
imap_unordered(func, iterable[, chunksize])
-
starmap(func, iterable[, chunksize])¶
-
starmap_async(func, iterable[, chunksize[, callback[, error_back]]])