Python篇-多进程与协程的理解与使用

TZ : 朴实的劳作也能硕果累累

一 : 科普一分钟

  • 尽管进程间是独立存在的,不能相互访问彼此的数据,但是在python中却存在进程间的通信方法,来帮助我们可以利用多核CPU也能共享数据.
  • 对于多线程其实也是存在一些缺点的,不是任何场景我们都用多线程来完成并发处理任务,因为CPU操作线程,所以线程多了,对于计算机的资源消耗是十分严重的,多线程适合IO操作密集的任务,那么怎么办呢, 协程的出现帮我们解决了这个问题 ,协程是比线程更小的一个单位,但是它的作用却不容忽视.

二 : 多进程

1. 多进程简单了解 :

进程之间是独立的,是操作系统自己来维护和管理的,python通过C接口起了一个进程,多进程可以充分的利用多核CPU

2. 多进程的创建 :
import  multiprocessing
import time

# 子进程执行方法
def run(person):
    time.sleep(2)
    print(person)

#循环创建 10个子进程
for i in  range(10):
#创建子进程实例
    p = multiprocessing.Process(target=run,args=('雪芙 %s' %i ,))
#运行子进程
    p.start()
3. 多进程间的通信 :

进程间独立,如果想相互访问,就必须有一个中间翻译,下面提供了几种进程间通信的方法

  • 进程Queue
from  multiprocessing import  Process,Queue

# import  queue

#子进程,内存独立,相当于数据的传递
def f(subQueue):
    subQueue.put("雪芙")

if __name__ == '__main__':
    #进程Queue
    q = Queue()
    #创建进程
    p = Process(target=f,args=(q,))
    #执行进程
    p.start()
    print(q.get())

解析 :
Queue通信,相当于父进程赋值了一个Queue给子进程,子进程在这个Queue放好数据后,序列化一个中间翻译,然后在反序列化返回给父进程,
因为进程之间内存独立,不能传递对象传递的其实就是序列化的数据

  • Pipe
    多进程还有一种数据传递方式叫管道原理和 Queue相同
# Author:TianTianBaby

from  multiprocessing import Process,Pipe

#子进程执行方法
def f(Subconn):
    Subconn.send("吃了吗")
    print("来自父亲的问候 : ",Subconn.recv())
    Subconn.close()


if __name__ == '__main__':
#创建管道两端
    parent_conn,child_conn = Pipe()
#创建子进程
    p = Process(target=f,args=(child_conn,))
    p.start()
    print("来自儿子的问候 :",parent_conn.recv())
    parent_conn.send("你好啊")
    p.join()
4. 进程锁

虽然内存独立,但是即使是打印也会造成打印数据错误,为了防止进程间抢屏幕打印输出,加了进程锁

from multiprocessing import  Process,Lock

#子进程执行方法
def f(lock,num):
    lock.acquire()
    print("tztztz",num)
    lock.release()

if __name__ == '__main__':
    lock = Lock()
#循环创建100个子进程
    for num in range(100):
        Process(target=f,args=(lock,num)).start()
5. 进程池

创建一个子进程相当于copy一份父进程内存数据,为了防止频繁创建,导致内存不足,所以有了进程池作为限制.

# Author:TianTianBaby

from multiprocessing import Process,Pool

import  time,os

def  son(i):
    time.sleep(2)
    return  i+100

def Back(arg):
    print('你好完成')


#允许进程池同时放入5个进程
pool = Pool(processes=3)

for i in range(10):
    #并行  callback 回调(主进程调用的)
    pool.apply_async(func=son,args=(i,),callback=Back)
   #并行
    # pool.apply_async(func=son, args=(i,))
    #串行
    # pool.apply(func=son,args=(i,))

print('end')
#先关闭进程池再join
pool.close()
#进程池中进程执行完毕再关闭,如果注释,那么程序直接关闭
pool.join()

三 : 协程

1. 协程的简单了解 :

协程又称微线程,coroutne,协程是一种用户态的轻量级线程

通俗点讲就是周末我在家里休息,假如我先洗漱,再煮饭,再下载电影看会很慢,用了协程的效果就好比,我在下载电影的时候去点火煮饭,此时我马上洗漱,等我洗漱好了,饭也好了,吃完饭了,电影下好了,我可以看了.

讲究效率的协程

2. 协程的创建和使用 :

gevent 是一个三方库,可以轻松通过gevent实现并发同步或者异步编程.

# Author:TianTianBaby

import  gevent
#函数1
def first():
    print('运行 1')
    gevent.sleep(2)
    print('回到1')#精确的文本内容切换到 ..

#函数2
def second():
    print('运行2')
    gevent.sleep(1)
    print('回到2')

#函数3
def third():
    print("运行3")
    gevent.sleep(0)
    print("回到3")

#创建并添加写成任务
gevent.joinall([gevent.spawn(first), #生成
                gevent.spawn(second),
                gevent.spawn(third)])

解析:尝试运行发现,运行时间为Sleep最长的时间,也就是说协程能绕过IO,进行执行,极大的提高了效率.
IO(从硬盘上读一块数据,从网络读数据,从内存里读一块数据) 操作不占用CPU,计算占用CPU

3. 协程简单爬网页 :
# Author:TianTianBaby
from urllib import  request
import  ssl
import gevent
from  gevent import  monkey

#把当前程序的所有的IO操作 单独做上标记
monkey.patch_all()
ssl._create_default_https_context = ssl._create_unverified_context
def f(url):
    print('GET:%s' %url)
    resp = request.urlopen(url)
    print(resp)
    data = resp.read()
    f = open("pa.html","wb")
    f.write(data)
    f.close()
    print("%d bytes received from %s" %(len(data),url))

gevent.joinall([gevent.spawn(f,'http://www.jianshu.com/'),
                gevent.spawn(f,'http://www.iconfont.cn/'),
                gevent.spawn(f,'http://www.cocoachina.com/'),
                ])
4. 协程实现socketServer:

通过协程,我们可以写出一个socketServer,真正socketServer的底层是用多线程来实现,我们用写成写出的效率很高,而且非常节省内存


import  sys
import  socket
import time
import gevent

from gevent import socket,monkey
monkey.patch_all()

def server(port):
    s = socket.socket()
    s.bind(('localhost',port))
    s.listen(500)
    while True:
        cli,addr = s.accept()
        #交给协程处理
        gevent.spawn(handle_request,cli)

def handle_request(conn):
    try:
        while True:
            data = conn.recv(1024)
            print("recv:",data)
            conn.send(data)
            if not data:
                conn.shutdown(socket.SHUT_WR)

    except  Exception as  ex:
        print(ex)

    finally:
        conn.close()

if __name__ == '__main__':
    server(9001)

四 : 总结

  • 协程的优点
    1 : 线程在单线程下切换,减少资源消耗
    2 : 无需原子操作控制流,简化编程模型
    3 : 高并发,高扩展,低成本.

  • 无论是多进程,多线程还是协程在不同的场景用不同的模型才能高效的完成任务.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容