首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

pyhton进程,线程,协程

进程,线程,协程

python多进程:

环境:Ubuntu,python3

python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing。

multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。

multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

生产者消费者实例:

ps:多进程之间无法直接通信,它必须借助一个第三方的桥梁 __队列(queue)__管道(pipe,Semaphore)

queue::

from multiprocessing import Process

import random

import time

import multiprocessing

def produce(name,q):

while True:

for i in range(5):

item = random.randint(1,5)

q.put(item)#将产品放入队列中

print("生产者",name,"生产了",str(item))

def consume(name,q):

while True:

for i in range(5):

item = q.get()#从队列中取出产品

print("消费者",name,"消费了",item)

if __name__ == '__main__':

q = multiprocessing.Queue(maxsize = 5)

Process(target=produce, args=(1,q)).start()

Process(target=consume, args=(2,q)).start()

#Process创建进程

#target一般是一个可调用对象,比如函数,类

# args传入参数

Semaphore::

from multiprocessing import Process

import random

import time

import multiprocessing

def produce(name,e,q):

while True:

for i in range(5):

e.acquire()#获取信号量,没信号量可用时,将进行阻塞

item = random.randint(1,5)

q.send(item)

print("生产者",name,"生产了",str(item))

def consume(name,e,q):

while True:

for i in range(5):

item = q.recv()

print("消费者",name,"消费了",item)

e.release()#释放信号量

if __name__ == '__main__':

con1, con2 = multiprocessing.Pipe()

#创建两个对象,进行通信

e = multiprocessing.Semaphore(5)

#acquire代表5个可用资源-1。

#release表示现有可用资源+1

Process(target=produce, args=(1,e,con1)).start()

Process(target=consume, args=(2,e,con2)).start()

python多线程:

环境:win10,python3

import random, threading

import queue

#生产者线程

class Producer(threading.Thread):

def __init__(self, name, queue):

threading.Thread.__init__(self, name=name)

self.queue = queue

def run(self):

for i in range(10):

print("%s 生产了 %d \n" % (self.getName(), i))

# 消费者线程

class Consumer(threading.Thread):

def __init__(self, name, queue):

threading.Thread.__init__(self, name=name)

self.queue = queue

def run(self):

for i in range(10):

print("%s 消费了 %d " % (self.getName(), val))

q = queue.Queue(maxsize = 5)

if __name__ == '__main__':

producer = Producer('生产者A', q)

consumer = Consumer('消费者B', q)

producer.start()

consumer.start()

协程:

环境:win10,python3

协程能保留上一次调用时的状态,每次协程重入时,就相当于进入上一次调用的状态。

从yield说起

一个带有 yield 的函数就是一个 generator(生成器),它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就返回一个迭代值,下次执行时从 yield 的下一个语句继续执行,返回当前的迭代值。

yiled和return区别:yield返回执行结果并不中断程序执行,return在返回执行结果的同时中断程序执行。

可以看看:廖雪峰老师的生成器:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00138681965108490cb4c13182e472f8d87830f13be6e88000

如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高,注意yield不但可以返回一个值,它还可以接收调用者发出的参数

def consumer():

print('启动生成器\n') # 只有第一次会执行(启动生成器), 之后再调用生成器就会从yield处执行

while True:

n = yield # Python的yield不但可以返回一个值,它还可以接收调用者发出的参数

print('接受到产品%s...'%n)

print('消费产品 %s...\n' % n)

def produce(c):

#c.send(None)

next(c)

#通过c.send(None)或者next(c)启动生成器函数,并执行到第一个yield语句结束的位置

print('开始生产产品...')

n = 0

while n

n = n + 1

print('生成产品 %s...' % n)

print('打包发送产品 %s...' % n)

r = c.send(n) # # 获取生成器consumer中由yield语句返回的下一个值

c.close()

if __name__ == '__main__':

c = consumer() #创建生成器

print('创建生成器')

produce(c)

源码地址:https://github.com/plusyou13/product/tree/master

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180607G00HXR00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券