# from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import requests
# import os
# import time
# import random
#
# def get(url):
# print('%s GET %s' %(os.getpid(),url))
# response=requests.get(url)
# time.sleep(random.randint(1,3))
#
# if response.status_code == 200:
# return response.text
#
# def pasrse(res):
# print('%s 解析结果为:%s' %(os.getpid(),len(res)))
#
# if __name__ == '__main__':
# urls=[
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.python.org',
#
# ]
#
# pool=ProcessPoolExecutor(4)
# objs=[]
# for url in urls:
# obj=pool.submit(get,url)
# objs.append(obj)
#
# pool.shutdown(wait=True)
# # 问题:
# # 1、任务的返回值不能得到及时的处理,必须等到所有任务都运行完毕才能统一进行处理
# # 2、解析的过程是串行执行的,如果解析一次需要花费2s,解析9次则需要花费18s
# for obj in objs:
# res=obj.result()
# pasrse(res) # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import requests
# import os
# import time
# import random
#
# def get(url):
# print('%s GET %s' %(os.getpid(),url))
# response=requests.get(url)
# time.sleep(random.randint(1,3))
#
# if response.status_code == 200:
# pasrse(response.text)
#
# def pasrse(res):
# print('%s 解析结果为:%s' %(os.getpid(),len(res)))
#
# if __name__ == '__main__':
# urls=[
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.python.org',
#
# ]
#
# pool=ProcessPoolExecutor(4)
# for url in urls:
# pool.submit(get,url)
# # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
# import requests
# import os
# import time
# import random
#
# def get(url):
# print('%s GET %s' %(os.getpid(),url))
# response=requests.get(url)
# time.sleep(random.randint(1,3))
#
# if response.status_code == 200:
# # 干解析的活
# return response.text
#
# def pasrse(obj):
# res=obj.result()
# print('%s 解析结果为:%s' %(os.getpid(),len(res)))
#
# if __name__ == '__main__':
# urls=[
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.baidu.com',
# 'https://www.python.org',
# ]
#
# pool=ProcessPoolExecutor(4)
# for url in urls:
# obj=pool.submit(get,url)
# obj.add_done_callback(pasrse)
#
# # 问题:
# # 1、任务的返回值不能得到及时的处理,必须等到所有任务都运行完毕才能统一进行处理
# # 2、解析的过程是串行执行的,如果解析一次需要花费2s,解析9次则需要花费18s
# print('主进程',os.getpid()) #解决问题: from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread
import requests
import os
import time
import random def get(url):
print('%s GET %s' %(current_thread().name,url))
response=requests.get(url)
time.sleep(random.randint(1,3)) if response.status_code == 200:
# 干解析的活
return response.text def pasrse(obj):
res=obj.result()
print('%s 解析结果为:%s' %(current_thread().name,len(res))) if __name__ == '__main__':
urls=[
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.baidu.com',
'https://www.python.org',
] pool=ThreadPoolExecutor(4)
for url in urls:
obj=pool.submit(get,url)
obj.add_done_callback(pasrse) print('主线程',current_thread().name)

异步+回调机制

线程queue:

1、队列:先进先出

# q=queue.Queue(3) #队列:先进先出
# q.put(1)
# q.put(2)
# q.put(3)
# # q.put(4)
#
# print(q.get())
# print(q.get())
# print(q.get())

队列

2、堆栈:后进先出

# q=queue.LifoQueue(3) #堆栈:后进先出
#
# q.put('a')
# q.put('b')
# q.put('c')
#
# print(q.get())
# print(q.get())
# print(q.get())

堆栈

3、优先级队列:可以以小元组的形式往队列理存值,第一个元素代表优先级,数字越小优先级别越高

q=queue.PriorityQueue(3)
q.put((10,'user1'))
q.put((-3,'user2'))
q.put((-2,'user3')) print(q.get())
print(q.get())
print(q.get())

优先级队列

Event: 进程之间协同工作

# from threading import Event,current_thread,Thread
# import time
#
# event=Event()
#
# def check():
# print('%s 正在检测服务是否正常....' %current_thread().name)
# time.sleep(3)
# event.set()
#
#
# def connect():
# print('%s 等待连接...' %current_thread().name)
# event.wait()
# print('%s 开始连接...' % current_thread().name)
#
# if __name__ == '__main__':
# t1=Thread(target=connect)
# t2=Thread(target=connect)
# t3=Thread(target=connect)
#
# c1=Thread(target=check)
#
# t1.start()
# t2.start()
# t3.start()
# c1.start() from threading import Event,current_thread,Thread
import time event=Event() def check():
print('%s 正在检测服务是否正常....' %current_thread().name)
time.sleep(5)
event.set() def connect():
count=1
while not event.is_set():
if count == 4:
print('尝试的次数过多,请稍后重试')
return
print('%s 尝试第%s次连接...' %(current_thread().name,count))
event.wait(1)
count+=1
print('%s 开始连接...' % current_thread().name) if __name__ == '__main__':
t1=Thread(target=connect)
t2=Thread(target=connect)
t3=Thread(target=connect) c1=Thread(target=check) t1.start()
t2.start()
t3.start()
c1.start()

Event

协程:

1、单线程下实现并发:协程

    并发指的多个任务看起来是同时运行的

    并发实现的本质:切换+保存状态

    并发、并行、串行:

    并发:看起来是同时运行,切换+保存状态

    并行:真正意义上的同时运行,只有在多cpu的情况下才能

      实现并行,4个cpu能够并行4个任务

    串行:一个人完完整整地执行完毕才运行下一个任务

# import time
# def consumer():
# '''任务1:接收数据,处理数据'''
# while True:
# x=yield
#
#
# def producer():
# '''任务2:生产数据'''
# g=consumer()
# next(g)
# for i in range(10000000):
# g.send(i)
#
# start=time.time()
# #基于yield保存状态,实现两个任务直接来回切换,即并发的效果
# #PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的.
# producer() #1.0202116966247559
#
#
# stop=time.time()
# print(stop-start) #
# import time
# def consumer(res):
# '''任务1:接收数据,处理数据'''
# pass
#
# def producer():
# '''任务2:生产数据'''
# res=[]
# for i in range(10000000):
# res.append(i)
#
# consumer(res)
# # return res
#
# start=time.time()
# #串行执行
# res=producer()
# stop=time.time()
# print(stop-start)

协程

单线程下实现IO切换:

# from greenlet import greenlet
# import time
#
# def eat(name):
# print('%s eat 1' %name)
# time.sleep(30)
# g2.switch('alex')
# print('%s eat 2' %name)
# g2.switch()
# def play(name):
# print('%s play 1' %name)
# g1.switch()
# print('%s play 2' %name)
#
# g1=greenlet(eat)
# g2=greenlet(play)
#
# g1.switch('egon') # import gevent
#
# def eat(name):
# print('%s eat 1' %name)
# gevent.sleep(5)
# print('%s eat 2' %name)
# def play(name):
# print('%s play 1' %name)
# gevent.sleep(3)
# print('%s play 2' %name)
#
# g1=gevent.spawn(eat,'egon')
# g2=gevent.spawn(play,'alex')
#
# # gevent.sleep(100)
# # g1.join()
# # g2.join()
# gevent.joinall([g1,g2]) # from gevent import monkey;monkey.patch_all()
# import gevent
# import time
#
# def eat(name):
# print('%s eat 1' %name)
# time.sleep(5)
# print('%s eat 2' %name)
# def play(name):
# print('%s play 1' %name)
# time.sleep(3)
# print('%s play 2' %name)
#
# g1=gevent.spawn(eat,'egon')
# g2=gevent.spawn(play,'alex')
#
# # gevent.sleep(100)
# # g1.join()
# # g2.join()
# gevent.joinall([g1,g2]) from gevent import monkey;monkey.patch_all()
from threading import current_thread
import gevent
import time def eat():
print('%s eat 1' %current_thread().name)
time.sleep(5)
print('%s eat 2' %current_thread().name)
def play():
print('%s play 1' %current_thread().name)
time.sleep(3)
print('%s play 2' %current_thread().name) g1=gevent.spawn(eat)
g2=gevent.spawn(play) # gevent.sleep(100)
# g1.join()
# g2.join()
print(current_thread().name)
gevent.joinall([g1,g2])

代码

异步、+回调机制、线程queue、线程Event、协程、单线程实现遇到IO切换的更多相关文章

  1. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

  2. python并发编程之Queue线程、进程、协程通信(五)

    单线程.多线程之间.进程之间.协程之间很多时候需要协同完成工作,这个时候它们需要进行通讯.或者说为了解耦,普遍采用Queue,生产消费模式. 系列文章 python并发编程之threading线程(一 ...

  3. Python之线程、进程和协程

    python之线程.进程和协程 目录: 引言 一.线程 1.1 普通的多线程 1.2 自定义线程类 1.3 线程锁 1.3.1 未使用锁 1.3.2 普通锁Lock和RLock 1.3.3 信号量(S ...

  4. python线程、进程和协程

    链接:http://www.jb51.net/article/88825.htm 引言 解释器环境:python3.5.1 我们都知道python网络编程的两大必学模块socket和socketser ...

  5. Python菜鸟之路:Python基础-线程、进程、协程

    上节内容,简单的介绍了线程和进程,并且介绍了Python中的GIL机制.本节详细介绍线程.进程以及协程的概念及实现. 线程 基本使用 方法1: 创建一个threading.Thread对象,在它的初始 ...

  6. python 线程,进程与协程

    引言 线程 创建普通多线程 线程锁 互斥锁 信号量 事件 条件锁 定时器 全局解释器锁 队列 Queue:先进先出队列 LifoQueue:后进先出队列 PriorityQueue:优先级队列 deq ...

  7. python队列、线程、进程、协程

    目录: 一.queue 二.线程 基本使用 线程锁 自定义线程池 生产者消费者模型(队列) 三.进程 基本使用 进程锁 进程数据共享 默认数据不共享 queues array Manager.dict ...

  8. python队列、线程、进程、协程(转)

    原文地址: http://www.cnblogs.com/wangqiaomei/p/5682669.html 一.queue 二.线程 #基本使用 #线程锁 #自定义线程池 #生产者消费者模型(队列 ...

  9. day21&22&23:线程、进程、协程

    1.程序工作原理 进程的限制:每一个时刻只能有一个线程来工作.多进程的优点:同时利用多个cpu,能够同时进行多个操作.缺点:对内存消耗比较高当进程数多于cpu数量的时候会导致不能被调用,进程不是越多越 ...

随机推荐

  1. 两篇 Spring 总结(一)

    Spring4 概述以及 HelloWorld 概述 Spring 是一个 IOC(DI) 和 AOP 容器框架. 轻量级,Spring 是非侵入的,即使用的时候不需要实现任何接口或继承任何父类 面向 ...

  2. 朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素

    朱晔的互联网架构实践心得S1E9:架构评审一百问和设计文档五要素 [下载文本PDF进行阅读] 本文我会来说说我认为架构评审中应该看的一些点,以及我写设计文档的一些心得.助你在架构评审中过五关斩六将,助 ...

  3. MongoDb 配置笔记

    安装: 官网:https://www.mongodb.org/ 按官方教程: http://docs.mongodb.org/master/tutorial/install-mongodb-on-re ...

  4. Python全栈开发之路 【第三篇】:Python基础之字符编码和文件操作

    本节内容 一.三元运算 三元运算又称三目运算,是对简单的条件语句的简写,如: 简单条件语句: if 条件成立: val = 1 else: val = 2 改成三元运算: val = 1 if 条件成 ...

  5. Randomized Online PCA Algorithms with Regret Bounds that are Logarithmic in the Dimension

    目录 Setup of Batch PCA and Online PCA Hedge Algorithm 改进算法 用于矩阵 \(rounding()\) 前俩次,都用到了\(rounding()\) ...

  6. 设计模式原则——依赖倒转&里氏代换原则

    设计模式一共有六大原则: 单一原则.开放封闭原则.接口分离原则.里氏替换原则.最少知识原则.依赖倒置原则. 这篇博客是自己对依赖倒转&里氏代换原则的一些拙见,有何不对欢迎大家指出. 依赖倒转原 ...

  7. 软工+C(8): 提问与回复

    // 上一篇:野生程序员 // 下一篇:助教指南 在线上博客教学里引入了第三方助教,助教在每次作业期间尽力完成"消灭零点评"的目标.然而紧接而来的问题是:学生对博客作业点评的回复率 ...

  8. java总结:Java中获取系统时间(年、月、日)以及下拉菜单默认选择系统年、月、日的方法

    <!-- 获取系统当前的年.月.日 --> <%@ page import="java.util.*"%> <% Calendar calendar= ...

  9. 【转】Linux下cp: omitting directory `XXX'问题解决

    在linux系统中复制文件夹时提示如下: Shell代码 [root@idtp4 site-packages]# /site-packages/ cp: omitting directory ‘yag ...

  10. Servlet 转发请求与重定向,以及路径问题

    转发请求 当一个servlet接收到请求后,如果需要将请求转发给另外一个servlet或者jsp文件,可使用下面这种方法: package cn.ganlixin.servlet; import ja ...