python多进程、多线程

1、多进程:

windows环境可以使用multiprocessing中的Process实现,该方法中有is_alive(), join(), run(), start(), terminate()方法:

Process的构造方法:

__init__(self, group=None, target=None, name=None, args=(), kwargs={})

参数说明:

group:进程所属组,基本不会用到;

target:表示调用对象

args:表示调用对象的位置参数元组

name:别名:

join()方法,和多线程类似,会阻塞主进程/主线程,直到其他进程或线程结束后,在运行主进程/线程;

[比如:当从进程/线程使用join方法后,就会提示主线程,需要等待“我”结束之后才会继续执行下去]

# coding=utf-8

import multiprocessing


def do(n):
    name = multiprocessing.current_process().name
    print(name, 'starting')
    print('worker', n)
    return


if __name__ == "__main__":
    numList = []
    for i in range(5):
        p1 = multiprocessing.Process(target=do, args=(i,))
        p2 = multiprocessing.Process(target=do, args=(i,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
        print("Process end")
2、Pool 

可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中,如果池还没有满,就会创建一个新的进程来执行请求,如果池满,请求就会告知请先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。Pool中的主要方法:apply()-python3之后不存在、 apply_async()、map()、close()、terminate()、join()。

apply_async() -非阻塞且支持结果返回进行回调

close() - 关闭进程池

terminate() 结束工作进程,不在处理未处理的任务

join() 主进程阻塞等待子进程的退出,join方法必须再close或terminate之后使用。

import time
from multiprocessing import Pool


def run(f):
    time.sleep(1)
    return f * f


if __name__ == "__main__":
    testFL = [1, 2, 3, 4, 5]
    print("order to run")
    s = time.time()
    for f in testFL:
        run(f)

    e1 = time.time()
    print("order to run"), int(e1 - s)
    print("concurrent")
    pool = Pool(2)
    r1 = pool.map(run, testFL)
    pool.close()
    pool.join()
    e2 = time.time()
    print("run time", int(e2 - e1))
    print(r1)

3、进程间通信-Queue

from multiprocessing import Process, Queue

def func(qq):
    qq.put("hello, Process")

if __name__ == "__main__":
    q = Queue()
    p = Process(target=func, args=(q,))
    p.start()
    print(q.get())
    print(q.get_nowait())
    p.join()

Queue中常用的方法:

  • Queue.qsize()  #获取队列的大小
  • Queue.empty() #判断队列是否为空, 空返回True,否则返回False
  • Queue.full()  #判断队列是否满,满返回True,否则返回False
  • Queue.get([block,[timeout]]) #获取队列内容,如果队列为空,则阻塞
  • Queue.get_nowait()  #与get()方法类似,不过如果队列为空,不等待,抛出空异常
  • Queue.put(item) #将item写入队列中,如果队列已满,则阻塞
  • Queue.put_nowait(item) #写入队列,如果队列已满,抛出异常(如果通过循环添加队列,循环大小超出队列大小,则一个item也添加不成功)
  • q = Queue(size) # 设置Queue的大小

除了基本的FIFO 队列外,还提供LIFO 队列[原则为后进先出],Priority Queue,存储元素时,使用优先级设置item在队列中的顺序【q.put(priority, item)】。

4、进程间通信-PIPE 


from multiprocessing import  Process, Pipe

def func(conn):
    conn.send("hello, parent !")
    conn.send("I'm ready!")
    print("parent answer:", conn.recv())
    conn.close()

if __name__ == "__main__":
    par_conn, child_conn = Pipe()
    p = Process(target=func, args=(child_conn,))
    p.start()
    print("child message", par_conn.recv())
    print("parent answer:", par_conn.send("hello son !"))
    p.join()

5、进程间通信manager、

其中,managers子模块支持把多进程分布到多台机器上,一个服务器进程作为调用者,多个客户端连接到服务器进程,执行多进程任务。

# job类
class Job:
    def __init__(self, job_id):
        self.job_id = job_id
#进程服务器
from multiprocessing import  Queue
from multiprocessing.managers import  BaseManager
from job import Job

class Master:

    def __init__(self):
        self.dispatched_job_queue = Queue()
        self.finished_job_queue = Queue()

    def get_dispatch_job_queue(self):
        return self.dispatched_job_queue

    def get_finished_job_queue(self):
        return self.finished_job_queue

    def start(self):
        BaseManager.register('get_dispatched_job_queue', callable=self.get_dispatch_job_queue)
        BaseManager.register('get_finished_job_queue', callable=self.get_finished_job_queue)

        key = "jobs".encode()
        manager = BaseManager(address=('127.0.0.1', 9988), authkey=key)
        manager.start()

        dispatched_jobs = manager.get_dispatched_job_queue()
        finished_jobs = manager.get_finished_job_queue()

        job_id = 0
        while True:
            for i in range(0, 10):
                job_id = job_id + 1
                job = Job(job_id)
                print('Dispatch job: %s' % job.job_id)
                dispatched_jobs.put(job)

            while not dispatched_jobs.empty():
                job = finished_jobs.get(60)
                print('Finished job: %s' % job.job_id)

        manager.shutdown()
if __name__ == "__main__":
    master = Master()
    master.start()
# 客户端进程
# coding: utf-8

from multiprocessing import Queue
from multiprocessing.managers import BaseManager
from job import Job
import  time

class Slave:
    def __init__(self):
        self.dispatched_job_queue = Queue()
        self.finished_job_queue = Queue()

    def start(self):
        BaseManager.register('get_dispatched_job_queue')
        BaseManager.register('get_finished_job_queue')

        server = '127.0.0.1'
        key = 'jobs'.encode()

        print("Connect to server %s... " % server)
        manager = BaseManager(address=(server, 9988), authkey=key)
        manager.connect()

        dispatched_jobs = manager.get_dispatched_job_queue()
        finished_jobs = manager.get_finished_job_queue()

        while True:
            job = dispatched_jobs.get(timeout = 1)
            print('Run job: %s' % job.job_id)
            time.sleep(1)
            finished_jobs.put(job)

if __name__ == "__main__":
    slave = Slave()
    slave.start()





阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页