zoukankan      html  css  js  c++  java
  • Python — 多进程

    multiprocessing

        multiprocessing包是Python中的多进程管理包。它可以利用multiprocessing.Process对象来创建一个进程。

        该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(),

        run(),join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多

        线程那样,通过参数传递给各个进程),用以同步进程。

    import multiprocessing
    import os
    
    
    def info(title):
        print(title)
        print(__name__)
        print('father', os.getppid())
        print('self', os.getpid())
        print('--------')
    
    
    
    if __name__ == "__main__": # 除了创建的子进程和子进程调用函数,其他的都是脚本主进程
        # info('hello')
        # 创建一个子进程调用函数
        P = multiprocessing.Process(target=info,args=('hello python',))
        P.start()
        P.join() # 和多线程一样,也是等待的意思
        print('hello word') # 若没有join则会独立运行

    RLock

     为了保证多线程任务执行时,共享资源的同步,出现了锁这个东西。

     Lock是阻塞其他线程对共享资源的访问,且同一线程只能acquire一次,如多于一次就出现了死锁,程序无法继续执行。

     为了保证线程对共享资源的独占,又避免死锁的出现,就有了RLock。RLock允许在同一线程中被多次acquire,线程对共

     享资源的释放需要把所有锁都release。即n次acquire,需要n次release。

    # 当进程进行文件读写操作的时候(关键性操作的时候)需要使用锁..
    from multiprocessing import Process,RLock
    import multiprocessing
    
    def _write(str_,lock):
        print(multiprocessing.current_process().name)
        # 写入文件
        path = '/Users/joker/Desktop/joker.txt'
    
        # with 会自己帮你关掉
        with lock:
        # 路径   模式a:追加  
    # 编码模式:utf-8, gbk,gb12128
    with open(path, mode='a',encoding='utf8') as f: f.write(str_) if __name__ == "__main__": ps = [] # 创建一个活锁 lock = RLock() for i in range(10): p = Process(target=_write,args=('今天天气好晴朗 ',lock)) p.start() ps.append(p) for i in ps: i.join()

     join

      描述

    • Python join( ) 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。

       语法

    •  join()方法语法:
      str.join(sequence)

     参数

    • sequence -- 要连接的元素序列。

    返回值

    • 返回通过指定字符连接序列中元素后生成的新字符串。

    实例

    •  以下实例展示了join()的使用方法  
    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
     
    str = "-";
    seq = ("a", "b", "c"); # 字符串序列
    print str.join( seq );
    •   输出结果
    a-b-c

    pipe

       Linux上,创建管道使用pipe函数,当它执行后,会产生两个文件描述符,分别为读端和写端。单个进程中的管道几乎没

       有任何作用,通常会先调用pipe,然后调用fork,从而创建从父进程到子进程的IPC通道。

    import multiprocessing
    
    def func(conn):
        conn.send(['Joker is a good man'])
        print('{} 发送了..'.format(multiprocessing.current_process().name))
        print('{} 接受了 {}'.format(multiprocessing.current_process().name,conn.recv()))
        conn.close()
    
    if __name__ == "__main__":
        conn_a,conn_b = multiprocessing.Pipe()
        p1 = multiprocessing.Process(target=func,args=(conn_a,)).start()
        conn_b.send([1, 2, 3, 4, 5, 6, 7])  # 发送数据给conn_a
        print('main',conn_b.recv())

    share

      '''
        全局变量不共享
        1809 ['a', 'b', 'c']
        1810 [1, 2, 3]
        '''
      
    # 全局变量不可以进程共享
    import multiprocessing
    import os
    data = []
    
    def List():
        global data
        data.append(1)
        data.append(2)
        data.append(3)
        print('p',os.getpid(),data)
    
    
    if __name__ == '__main__':
        p = multiprocessing.Process(target=List,args=()).start()  # 子进程
        data.append('a')  # 脚本主进程
        data.append('b')
        data.append('c')
        print('main',os.getpid(),data)

    queue

        queue详情可阅读

       https://docs.python.org/zh-cn/3/library/queue.html#queue.Queue.task_done
    import multiprocessing
    import time
    ############################################################################
    # https://docs.python.org/zh-cn/3/library/queue.html#queue.Queue.task_done #
    ############################################################################
    
    
    # 一定是要一个放,一个取
    # maxsize 设置队列的最大长度.
    queue = multiprocessing.Queue(maxsize=10)
    def func1(queue):
        while 1:
            print('放入..')
            queue.put(100,timeout=3)
    
    def func2(queue):
        while 1:
            time.sleep(3)
            res = queue.get()
            print(res)
    
    if __name__ == "__main__":
        p1 = multiprocessing.Process(target=func1,args=(queue,))
        # p2 = multiprocessing.Process(target=func2,args=(queue,))
    
        p1.start()
        # p2.start()
        p1.join()
        # p2.join()

    进程列表数据共享

    # 创建一个共享的列表/数组
    # 当你有多个进程需要同时操作某一个数组的时候,你就应该搭建一个共享数组Array.
    import multiprocessing
    
    def func(m,i):
        m[i] = 10000
     
    def func1():
        # Array 是一个对象
        list_ = multiprocessing.Array('i',[1,2,3])
        return list_
    
    
    if __name__ == "__main__":
        list_ = func1()
        print(list_[:])
        p1 = multiprocessing.Process(target=func,args=(list_,0))
        p2 = multiprocessing.Process(target=func,args=(list_,1))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
    
        print(list_[:])
    #列表里的:(冒号)代表全选

    进程字典列表共享

    import multiprocessing
    
    
    def func(mydict, mylist):
        mydict["胡旺"] = "牛皮"
        mydict["lalal"] = "大美女"
        mylist.append(11)
        mylist.append(22)
        mylist.append(33)
    
    
    if __name__ == "__main__":
        # with multiprocessing.Manager() as MG:
        #     mydict=MG.dict()
        #     mylist=MG.list(range(5))
        mydict = multiprocessing.Manager().dict()
                                            # [0,1,2,3,4]
        mylist = multiprocessing.Manager().list(range(5))
    
        p = multiprocessing.Process(target=func, args=(mydict, mylist))
        p.start()
        p.join()
    
        print(mylist)
        print(mydict)
        # print(list(range(5)))  # 很牛逼的list

     

  • 相关阅读:
    Android studio快捷键大全 和 eclipse对照(原)
    .net 提取注释生成API文档 帮助文档
    查看443端口被占用无法启动解决办法
    关于正则表达式 C#
    关于 ImageLoader 说的够细了。。。
    什么时候用Application的Context,什么时候用Activity的Context
    关于layoutparam 请铭记。。。。
    java 静态方法上的泛型
    让多个Fragment 切换时不重新实例化
    开源.net 混淆器ConfuserEx介绍
  • 原文地址:https://www.cnblogs.com/liyuanyuan97/p/11342421.html
Copyright © 2011-2022 走看看