首页 > 其他 > 详细

并发编程之 协程

时间:2019-08-16 13:57:32      阅读:60      评论:0      收藏:0      [点我收藏+]

协程 (单线程下实现并发)

  进程:资源单位

  线程:执行单位

  协程:单线程下实现并发

并发:切换+保存状态

程序员自己通过代码自己检测程序中的IO

一旦遇到了IO自己通过代码切换

给操作系统的感觉就是你这个线程没有任何的IO    从而提升代码的运行效率

 

切换+保存状态一定能够提升效率吗?

  1.当任务是IO密集型的情况下     提升效率

     2.当任务是计算密集型的情况下    降低效率

 

接下来 我们进行验证  

1.在计算密集型的情况下,通过切换+保存状态   效率到底是降低了还是提升了呢?

这是串行执行的时间:

# 串行执行 0.8540799617767334
import time

def func1():
    for i in range(10000000):
        i+1

def func2():
    for i in range(10000000):
        i+1

start = time.time()
func1()
func2()
stop = time.time()
print(stop - start)

下面是切换+保存状态的执行时间:

#基于yield并发执行  1.3952205181121826
import time
def func1():
    while True:
        10000000+1
        yield

def func2():
    g=func1()
    for i in range(10000000):
        time.sleep(100)  # 模拟IO,yield并不会捕捉到并自动切换
        i+1
        next(g)

start=time.time()
func2()
stop=time.time()
print(stop-start)

根据执行时间来看  明显效率是降低了

2.在IO密集型的情况下,通过切换+保存状态   效率到底是降低了还是提升了呢?

首先我们需要找到一个能够识别IO的工具,遇到IO就可以自动的切换

这里我们就用到了gevent模块

这是串行的执行结果:

 

from gevent import monkey;monkey.patch_all()
from gevent import spawn
import  time

‘‘‘
注意  gevent模块没办法自动识别 time.sleep 等io情况
需要你手动配置一个参数
‘‘‘

def heng():
    print(哼!)
    time.sleep(2)
    print(哼!)

def ha():
    print(哈!)
    time.sleep(3)
    print(哈!)

start = time.time()

heng()
ha()

print(time.time()-start)
#5.041796445846558

 

下面是通过切换+保存状态来执行  利用gevent模块

from gevent import monkey;monkey.patch_all()
from gevent import spawn
import  time

‘‘‘
注意  gevent模块没办法自动识别 time.sleep 等io情况
需要你手动配置一个参数
‘‘‘

def heng():
    print(哼!)
    time.sleep(2)
    print(哼!)

def ha():
    print(哈!)
    time.sleep(3)
    print(哈!)

start = time.time()

g= spawn(heng)
g1 = spawn(ha)
g.join()
g1.join()

print(time.time()-start)

#3.041301727294922

明显的看出在IO密集型的情况下  切换+保存状态能够提升效率

 

Gevent应用举例 

利用协程实现并发

实现TCP服务端的并发

server端

import socket
from gevent import monkey;monkey.patch_all()
from gevent import spawn

sk = socket.socket()
sk.bind((127.0.0.1, 8080))
sk.listen()
def talk(conn):
    while True:
        try:
            data = conn.recv(1024)
            if len(data) == 0 :break
            print(data.decode(utf-8))
            conn.send(bhi)
        except ConnectionResetError as e:
            print(e)
            break
    conn.close()

def server():
    while True:
        conn,addr = sk.accept()
        spawn(talk,conn)

if __name__ == __main__:
    res = spawn(server)
    res.join()

client端 起了400个线程

from threading import Thread
import socket

def client():
    sk = socket.socket()
    sk.connect((127.0.0.1,8080))


    while True:
        sk.send(bhello)
        data = sk.recv(1024).decode(utf-8)
        print(data)

for i in range(400):
    t = Thread(target=client)
    t.start()

 

并发编程之 协程

原文:https://www.cnblogs.com/s686zhou/p/11363057.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!