您的位置:首页 > 理论基础 > 计算机网络

7.11-Python-语言及其应用-笔记-并发和网络--未完

2017-07-11 22:13 351 查看
在多个地方(分布式计算)同时做很多事情(并发)

优势:鲁棒性?

并发

2.1 程序等待的原因:I/O限制,CPU限制

2.2 和并发 相关的名词解释

同步:事情一件件发生,送葬的概念

异步: 任务之间相互独立

处理长时间的任务,(队列)

之前介绍了使用多进程的方式(增加进程)达到并发的工作,比如需要改变图片的大小,web服务器可以 单独的调用一个图片处理进程,解决这个问题,达到使得程序可以并发执行的效果

介绍一种多任务管理方法:队列! 特点是先进先出,用来管理分布式任务的队列叫做“工作队列”,

利用队列的知识点解释洗盘子的问题 ,队列是用来传递消息的,利用队列管理分布式任务,水池里面的盘子会交给第一个空闲洗盘子的人,洗完后会交给第一个擦盘子的人,擦完盘子以后会交给第一个烘盘子的人,烘 完盘子交给第一个访盘子的人,队列强调的是第一个洗好的盘子会第一个拿去烘干,顺序是不会发生变动的

同步和异步的区别在于,是不是需要等擦盘子的人有空闲以后才让洗盘子的人把盘子给他(同步),还是说洗盘子的人结束以后就不管了,把盘子放在地上,随便他什么时候自己去取

利用几个独立进程
multiprocessing
进行通信,实现队列的效果,
dish_queue.join()
进程结束的标志

import multiprocessing as mp

def washer(dishes,output):
for dish in dishes:
print ('Washing',dish,'dish')
output.put(dish)

def dryer(input):
while True:
dish = input.get()
print ('Dryin',dish,'dish')
input.task_done()

dish_queue = mp.JoinableQueue()
dryer_proc = mp.Process(target =dryer,args=(dish_queue,))
dryer_proc.daemon = True
dryer_proc.start()

dishes = ['salad','bread','entree','dessert']
washer(dishes,dish_queue)
dish_queue.join()


线程的解释,运行在进程的内部,可以访问进程的所有的内容,
multiprocessing
threading
两个模块分别代表了进程和线程,感觉量级别的不同

使用线程完成进程的操作

import threading
def do_sth(what):
whoami(what)

def whoami(what):
print ('Thread %s says %s '%(threading.current_thread(),what))
if __name__ =="main":
whoami("I am the main program")
for i in range(4):
p = threading.Thread(target=do_sth,args=("I am function %s"%n))
p.start()


使用线程完成洗盘子的功能,
dishes_queue
表示生成队列,
dryer_thread = threading.thread()
表示 定义一个线程

import threading,queue
import time
def washer(dishes,dish_queue):
for dish in dishes:
print ('Washing',dish)
time.sleep(5)
dish_queue.put(dish)

def drydish(dish_queue):
while True:
dish = dish_queue.get()
print ("Drying",dish)
dish_queue.task_done()

dish_queue = queue.Queue()
for i in range(2):
dryer_thread = threading.Thread(target=dryer,args=(dish_queue,))
dryer_thread.start()

#队列定义dish_queue,
dishes = ['salad','bread','entree','desert']
washer(dishes,dish_queue)
dish_queue.join()


线程和进程之间的不同,线程没有终止函数,一个运行中的线程很难终止,并且线程之间没有共享的全局变量,

线程和进程之间的关系是可以使用”房间+幽灵”的方式解释的,线程是房间,进程是幽灵,房间中的物件是变量,

在处理有全局变量的线程时,需要在县城修改变量之前使用到”软件锁”,这样子在修改的时候,其他的进程也需要等待,锁可以嵌套,也别忘记解锁!

11.1.4 绿色线程和gevent

开发者把程序中运行速度比较慢的部分开始划分成多个线程或者是多个进程,比如Apache Web服务器,还有另外一种方法

基于事件编程,一个基于事件的程序会循环一个核心事件循环,比如Nginx Web,现在介绍 gevent 库,主要功能是把普通代码转换成”协程”

“协程”的解释:类似于一个相互通信的生成器,它们会自己记录自己的位置,然后修改python很多的标准对象,比如socket,使他们使用自己的机制避免阻塞,但是“协程”没有办法处理C 写的python扩展代码

利用
gevent
模块
gevent.spawn
函数 创建一个微线程(绿色线程),微线程和普通线程区别在于,微线程不会阻塞,如果遇到阻塞,
gevent
是可以把控制权切换到别的绿色线程上的

import gevent
from gevent import socket
hosts = ['www.crappytaxidermy.com','wwww.walterpottertaxidermy.com','www.antique-taxidermy.com']
jobs = [gevent.spawn(gevent.socket.gethostbyname,host)for host in hosts]
#等待所有任务完成的函数joinall()
gevent.joinall(jobs,timeout=5)
for job in jobs:
print (job.value)


使用猴子补丁(monkey-patching)函数可以修改标准模块,比如
socket
,让他们直接使用微线程,而不是通过
spawn
的方式 进行使用了微线程,把下面的代码加在开头就可以充分利用gevent 带来的速度提升!

import gevent,
from gevent import monkey;monkey,patch_all()


gevent
对于大型网站有明显的加速作用,还有两个流行的事件驱动是
tornado
gunicorn
,他们都是 使用底层事件处理和加速 web服务器 ,如果 你使用的是传统的web服务器比如
Apache
就可以 上面 两个 事件驱动 进行构建高速网站

11.1.5 异步事件驱动的网络框架 twisted

把函数关联到具体的事件上去,当事件发生的时候就会被调用函数,这种方式成为“回调”,

11.1.7 利用 Redis 服务器 创建一个队列

利用python模块把 数据添加 到一个 dish队列 中 ,这个 dish队列 用
conn = redis.Redis()
生成的 ,增加多个
Dryer.py
进程 ,使用
os.getpid()
的方式获得 进程识别码 ,
multiprocessing.Process(target=dryer)
表示同时创建多个进程 进行工作

11.1.8 使用 队列的 控制层

具体的可以看一下
celery
包 ,里面使用了
multiprocessing
gevent
等 方法

11.2 跨空间的分布式计算(网络化)

11.2.2 不同模式进行搭建网络化应用

“请求–响应”/“客户端–服务器端”,该模式是同步的,客户端会一直等待服务器端的响应

“推送”/“扇出”,数据请求发送到进程池,等有空的工作进程进行处理

“ ”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: