python3 语法之多进程

来源:互联网 发布:大数据的技术要点 编辑:程序博客网 时间:2024/06/05 06:12

1.创建一个多进程

  • 需要导入multiprocessing 模块
  • 创建多进程时需要加入一个if 判断 即:
if __name__ == "__main__" :    function(创建多进程的语句)

例子(创建一个多进程):

import osimport multiprocessing #导包多进程import timedef go(n):    print("中华人民共和国",n)    print("父进程",os.getppid()) #打印父进程    print("子进程",os.getpid()) #打印子进程    time.sleep(2)if __name__ =="__main__":    mypid=multiprocessing.Process(target=go,args=(3,)) #创建多进程    mypid1 = multiprocessing.Process(target=go, args=(6,))  #创建多进程    mypid.start() #开启进程    mypid1.start()    mypid.join() #    mypid1.join()

2,多进程中,每个子进程都会拷贝一份全局变量,所以,主进程对全局变量的改变不会影响子进程。

import multiprocessing #导包多进程import timeimport osnum=100def go(newnum):    global num    print(num)    print("主线程:",os.getppid())    print("子线程:",os.getpid())    num=newnum    print(num)    print("分隔符".center(50,"-"))if __name__ == "__main__":    go(2) #主进程    pid=multiprocessing.Process(target=go,args=(33,)) #创建一个子进程    pid.start() #开启子进程    pid.join() #阻塞主进程,等待子进程执行结束后,主进程再继续执行下面的语句执行结果为:100主进程: 3476 #该主进程是pycharm中自带的的启动进程子进程: 5800 #代码中的主进程2-----------------------分隔符------------------------100主进程: 5800 #代码中的主进程子进程: 15176 #代码中创建的子进程pid33-----------------------分隔符------------------------

3,多进程的顺序执行与乱序(并发)执行

import timeimport  multiprocessingimport  osdef  TestGo(title):    print(title)    print(__name__) #执行模块的名称    print("father pid", os.getppid())  # 获取父进程编号    print("self  pid", os.getpid())  # 获取进程编号    time.sleep(2)if __name__=="__main__":    TestGo("王毅")    p1=multiprocessing.Process(target=TestGo,args=("小明1",))    p2=multiprocessing.Process(target=TestGo, args=("小明2",))    p3=multiprocessing.Process(target=TestGo,args=("小明3",))    '''并发    p1.start()    p2.start()    p3.start()    p1.join()    p2.join()    p3.join()    '''    p1.start() #顺序    p1.join()    p2.start()    p2.join()    p3.start()    p3.join()

4,多进程中锁的定义方法以及利用锁限制子进程顺序执行。

import timeimport  multiprocessingimport  os# mutex = multiprocessing.Lock() 可以将锁定义在函数或类外面的适当位置def  TestGo(mutex,title):    print(title)  #上半段子进程并发执行    with  mutex: #下半段,加锁之后,子进程排队顺序执行        time.sleep(2)        print(__name__) #执行模块的名称        print("father pid", os.getppid())  # 获取父进程编号        print("self  pid", os.getpid())  # 获取进程编号if __name__=="__main__":    mutex = multiprocessing.Lock() # 定义一把锁 ,该锁可以当作一个参数传入,也可在类中定义为全局变量    TestGo(mutex,"王毅")    namelist=["房久博","王雪飞","李培伦","王涛"]    plist=[]#进程列表    for  name  in namelist:        p=multiprocessing.Process(target=TestGo,args=(mutex,name,))        p.start()        plist.append(p)    for  p  in plist:        p.join()    print("主进程结束") # 此处的print语句要放在 if 语句内才是程序主进程的内容#print("主进程结束") #如果print语句位置与if 语句对齐的话,打印结果会与上面的不同(具体原因不太清楚)

5,多进程中,通过管道pipe 来传递信息

  • 如何定义管道
  • 管道的一头发消息,另一头接消息(管道实现的只是数据的传递,而不是共享)
import timeimport multiprocessingimport osdef go(conn):    conn.send(["来自父亲的问候:孩儿最近可好?"]) # 管道的一头发消息(注意发消息的格式)    print(os.getpid(),conn.recv())    conn.close()if __name__ == "__main__":    parent_conn,son_conn = multiprocessing.Pipe() # 创建两个管道    mypid=multiprocessing.Process(target=go,args=(parent_conn,)) # 创建一个进程,将管道的一头传入函数    mypid.start()  #开启进程    print(os.getpid(), son_conn.recv()) # 管道的另一头接收消息    son_conn.send(["父皇万岁"]) #管道的两个可以互相发送和接收消息(双向性)    mypid.join()

6,多进程中,实现数据共享的几种方法

1. 方法一:通过队列来实现进程之间的传递

需要注意几点:
(a):多进程中队列的创建方式
(b):将数据压入队列和从队列取出的格式 :queue.put([]),queue.get([])

import multiprocessing # 导包多进程import timeimport osqueue=multiprocessing.Queue() # 多进程中,队列创建的方法# 栈,是先进后出,队列,是先进先出def getandput(queue):    queue.put(["苏州", "香港"])  # 将数据压入队列    queue.put(["北京","上海","杭州"]) # 将数据压入队列    print(os.getpid(), queue.get())if __name__ == "__main__":    mypid=multiprocessing.Process(target=getandput,args=(queue,)) # 创建一个进程    mypid.start() # 开启进程    print(os.getpid(), queue.get())    mypid.join() 执行结果为:12668 ['苏州', '香港']2604 ['北京', '上海', '杭州']

2,方法二:通过进程中的value来实现进程间的数据共享

需要注意几点:
(a):多进程中value 的创建方式
(b):value 值的定义和调用

import multiprocessingimport osimport timedef go(num):    num.value=13    print(os.getpid(),num.value) # 子进程执行    time.sleep(4)if __name__ == "__main__":    num=multiprocessing.Value("d",10) # d 代表整数型    print(os.getppid(),num.value) # 主进程    mypid=multiprocessing.Process(target=go,args=(num,))    mypid.start()    mypid.join()    print(os.getppid(), num.value) # 主进程结果为:11408 10.09228 13.011408 13.0

3,方法三:通过进程中的array来实现进程间的数据共享(array只用来传递数组)

需要注意几点
(a):多进程中array 的创建方式
(b):array 值的定义和调用

import multiprocessingdef go(array):    array[1]=222 # 注意,array只能修改,不能增加元素    print(array[:]) # 子线程if __name__ == "__main__":    array=multiprocessing.Array("i",[1,2,3,4,5]) # i 为整型,array 用来传数组    print(array[:]) # 主线程    mypid=multiprocessing.Process(target=go,args=(array,))    mypid.start()    mypid.join()结果为:[1, 2, 3, 4, 5][1, 222, 3, 4, 5]

4,方法四:通过进程中的字典和列表来实现进程间的数据共享

import multiprocessingdef func(mydict, mylist):    mylist.append(10)    mylist.append(11) #子进程完成对数据的修改    mylist.append(12)    mydict["小亮"]=175 #子进程完成对数据的修改if  __name__=="__main__":    mydict=multiprocessing.Manager().dict() # 多进程中的字典创建    mylist=multiprocessing.Manager().list(range(5)) # 多进程中的列表创建    mydict["小明"]=180    print(mylist) # 主进程    print(mydict)  # 主进程    print("分隔符".center(50,"-"))    p=multiprocessing.Process(target=func,args=(mydict, mylist)) # 创建子进程    p.start()    p.join()    print(mylist)  # 主进程    print(mydict)  # 主进程结果为:[0, 1, 2, 3, 4]{'小明': 180}-----------------------分隔符------------------------[0, 1, 2, 3, 4, 10, 11, 12]{'小明': 180, '小亮': 175}

七:多进程中的线程池

  • 注意进程中线程池如何定义

- 进程中线程池的同步和异步执行方式。

import timeimport  multiprocessingimport  osdef  TestGo(title):    print(title)  #上半段并发    time.sleep(5)    print(__name__) #执行模块的名称    print("father pid", os.getppid())  # 获取父进程编号    print("self  pid", os.getpid())  # 获取进程编号if __name__=="__main__":    namelist=["苏州","上海","北京","杭州"]    pool=multiprocessing.Pool(3) # 创建进程池,限制个数,只能三个进程同时执行(进程池用来限制多进程并发执行的个数,由于计算机内部其他原因,多进程并发执行时,会存在执行时间误差(即不会精确的同时完成某个任务,有的先完成有的后完成,但都是同步执行的),当进程池中某个进程完成任务时,进程池外部的进程会自动加入进程池,以保证进程池中进程的个数))限制并发进程数量    for  name in namelist:        # pool.apply(TestGo,(name,)) # 同步(顺序执行)        pool.apply_async(TestGo,args=(name,)) #异步(并发执行),注意函数名和参数传递的细节。    pool.close()#结束插入进程,开始执行    pool.join()#等待    print("完成")