python进程

由于进程之间的数据需要各自持有一份,所以创建进程需要非常大的开销。

from multiprocessing import Process
import time


def foo(i, arg):
    print('say hi', i)
    arg.append(i)
    time.sleep(1)
    print(arg)

li = []
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        #p.daemon = True     #主进程是否等待子进程,默认为False等待
        p.start()
        #p.join()        
创建进程

进程间默认是不能数据共享的,可以通过人为实现:

from multiprocessing import Process
from multiprocessing import queues
import multiprocessing


def foo(i, arg):
    arg.put(i)
    print('say hi', i, arg.qsize())

li = queues.Queue(20,ctx=multiprocessing)
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        p.start()
通过queue实现

数组必须是创建时规定类型和长度

from multiprocessing import Process
from multiprocessing import Array   #数组


def foo(i, arg):
    arg[i] = i + 100
    for item in arg:
        print(item)
    print('++++++++')
if __name__ == '__main__':
    li = Array('i', 10)
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        p.start()
通过数组实现
数组类型对应表:  
  'c': ctypes.c_char, 'u': ctypes.c_wchar, 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, 'h': ctypes.c_short, 'H': ctypes.c_ushort, 'i': ctypes.c_int, 'I': ctypes.c_uint, 'l': ctypes.c_long, 'L': ctypes.c_ulong, 'f': ctypes.c_float, 'd': ctypes.c_double
from multiprocessing import Process
from multiprocessing import Manager #特殊字典


def foo(i, arg):
    arg[i] = i+100
    print(arg.values())


if __name__ == '__main__':
    obj = Manager()
    li = obj.dict()
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        p.start()
    time.sleep(0.6)
# 当主进程执行完毕后,子进程与主进程的连接断开,
# 所以便不能修改主进程字典,所以报错,但是可以看到几个,可一将时间修改长一些
通过特殊字典实现

当创建进程时(非使用时),共享数据会被拿到子进程中,当进程中执行完毕后,再赋值给原值。

进程锁:(和线程锁相同)

# 进程锁,未加锁,执行中会产生脏数据。
from multiprocessing import Array
NUM = 9         #普通的数据类型是不能共享的


def foo(i, li):
    li[0] -= 1
    global NUM
    NUM -= 1
    time.sleep(1)
    print(li[0], NUM)

li = Array('i', 1)
li[0] = 10
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        p.start()
未加锁
# 进程锁,已加锁,其方法与线程锁基本相同
from multiprocessing import Array
from multiprocessing import RLock, Lock, Event, Condition


def foo(i, li):
    li.acquire()
    li[0] -= 1
    time.sleep(1)
    print(li[0])
    li.release()

li = Array('i', 1)
li[0] = 10
lock = RLock()
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=foo, args=(i, li))
        p.start()
加锁后

进程池:

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:apply和apply_async

#进程池,默认有进程池
from multiprocessing import Pool


def foo(arg):
    time.sleep(1)
    print(arg)

if __name__ == '__main__':
    pool = Pool(5)
    for i in range(30):
        # apply方法是去进程池中取进程,进程间为串行,非并行
        pool.apply(func=foo, args=(i,))
        #pool.apply_async(func=foo, args=(i,))
    print('end')
进程池
from multiprocessing import Pool


def foo(arg):
    time.sleep(0.1)
    print(arg)

if __name__ == '__main__':
    pool = Pool(5)
    for i in range(30):
        pool.apply_async(func=foo, args=(i,))

    # close方法表示所有的任务执行完毕后再继续往下执行
    # pool.close()
    time.sleep(0.5)
    # terminate表示立即终止,不管任务是否执行完毕,立即终止再继续往下执行
    pool.terminate()
    pool.join()
    print('end')
进程池
原文地址:https://www.cnblogs.com/caibao666/p/6772915.html