python多进程、多线程

转载 2018年04月15日 22:59:39

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()





Python多线程与多进程

查看原文:http://www.wyblog.cn/2016/12/05/python%e5%a4%9a%e7%ba%bf%e7%a8%8b%e4%b8%8e%e5%a4%9a%e8%bf%9b%e7...
  • wy250229163
  • wy250229163
  • 2016-12-22 21:22:53
  • 2268

python中多进程和多线程的配合使用

由于python的多线程中存在PIL锁,因此python的多线程不能利用多核,那么,由于现在的计算机是多核的,就不能充分利用计算机的多核资源。但是python中的多进程是可以跑在不同的cpu上的。因此...
  • nfzhlk
  • nfzhlk
  • 2017-08-09 06:47:19
  • 836

为什么在Python里推荐使用多进程而不是多线程?

转载地址  最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢?   要知其然,更要知其所以然。所以有了下面的深入研...
  • universe_ant
  • universe_ant
  • 2016-04-25 16:19:09
  • 10088

python爬虫(中)--多进程和多线程

前面我们见到了基本爬虫的请求、提取和保存,这是一个基本爬虫应该有的结构,那么这时候的这个爬虫有了能爬能存的能力,但是这种能力是很弱的,弱主要体现在三点:①爬虫本身健壮性并不高,有很多情况不一定考虑到;...
  • qq_29245097
  • qq_29245097
  • 2016-08-26 17:41:30
  • 4078

Python中单线程、多线程和多进程的效率对比实验

Python是运行在解释器中的语言,查找资料知道,python中有一个全局锁(GIL),在使用多进程(Thread)的情况下,不能发挥多核的优势。而使用多进程(Multiprocess),则可以发挥多...
  • u011489043
  • u011489043
  • 2017-04-03 21:22:49
  • 403

搞定python多线程和多进程

1 概念梳理: 1.1 线程1.1.1 什么是线程线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多...
  • loguat
  • loguat
  • 2017-07-10 13:14:11
  • 942

Python多进程、多线程、协程学习小结

Python多进程、多线程、协程学习小结
  • yiranyaoqiu
  • yiranyaoqiu
  • 2016-11-30 22:02:53
  • 797

Python :多线程和多进程的选择

如果你的代码是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有context switch。 如果你的代码是IO密集型,多线程可以明显提高效率...
  • xiaofei0859
  • xiaofei0859
  • 2016-10-31 15:10:01
  • 445

Python多线程、异步+多进程爬虫实现代码

安装Tornado 省事点可以直接用grequests库,下面用的是tornado的异步client。 异步用到了tornado,根据官方文档的例子修改得到一个简单的异步爬虫类。可以参考下最新的文档...
  • zhangtian6691844
  • zhangtian6691844
  • 2016-06-17 15:36:13
  • 1377
收藏助手
不良信息举报
您举报文章:python多进程、多线程
举报原因:
原因补充:

(最多只允许输入30个字)