python协程,线程的其他方法

OK 这一篇主要是协程的,还落下了点线程的方法,先说线程,

  1. 线程池
  2. 线程池回调函数
  3. 协程

一. 线程池  

   线程池顾名思义就是跟是跟进程池一样的

  到这里就差我们的线程池没有讲了,我们用一个新的模块给大家讲,早期的时候我们没有线程池,现在python提供了一个新的标准或者说内置的模块,这个模块里面提供了新的线程池和进程池,之前我们说的进程池是在multiprocessing里面的,现在这个在这个新的模块里面,他俩用法上是一样的。

为什么要将进程池和线程池放到一起呢,是为了统一使用方式,使用threadPollExecutor和ProcessPollExecutor的方式一样,而且只要通过这个concurrent.futures导入就可以直接用他们两个了  

import    time
from   threading   import   current_thread        #这里还是要导入线程的current_thread方法,因为要用。
from   concurrent.futures   import    ThreadPoolExecutor,ProcessPoolExecutor    #这里直接就把进程,线程一起导入了,省事!呵呵呵。。。

def   f1(n,s):
  time.sleep(1)
  # print(‘%s号子线程‘%current_thread().ident)
  print(n,s)
  return

if __name__ == ‘__main__‘:

  tp = ThreadPoolExecutor(4)    #线程池的方法(4)个线程
  # tp = ProcessPoolExecutor(4)
  # tp.map(f1,range(10))        #异步提交任务,参数同样是任务名称,可迭代对象
  res_list = []
  for i in range(10):
    res = tp.submit(f1,i,‘baobao‘)      #submit是给线程池异步提交任务,
    #print(res)
    res.result()                       #取值这一步相当于把线程变成了一个同步的状态,这一步
    res_list.append(res)        #是为了取到f1中return的值,才这样取值的,要不就直接加个

                    #tp.shutdown() 直接就四个四个打印了。所以才加的列表。 
  

  tp.shutdown()            #主线程等待所有提交给线程池的任务,全部执行完毕 close + join
  for r in res_list:             #加到列表里是为了能四个四个取值,把所有的返回值地址放到一个列表
    print(r.result())        #再循环取值,这样就能四个四个拿值了,要不这样的话,就成了同步取值
  print(‘主线程结束‘)        #了就没效率了

二.线程的回调函数

跟进程一样,单词不一样。

import    time
from   threading   import   current_thread
from    concurrent.futures    import    ThreadPoolExecutor,ProcessPoolExecutor

def   f1(n,s):
  return n+s

def   f2(n):

  print(‘回调函数>>>‘,n.result())
if __name__ == ‘__main__‘:

  tp = ThreadPoolExecutor(4)

  res = tp.submit(f1,11,12).add_done_callback(f2)       #把f1的值,返回给f2  记住方法add_done_callback(f2)

  # print(res.result())

三.协程

  进入主题--协程

  协程  这个词在官方中是没有定义这样的一个方法的,这个说句大白话,协程 这个方法是

  大佬程序员,自己YY出来的。

本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态

  cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它

  协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销(开关线程,创建寄存器、堆栈等,在他们之间进行切换等),在我们自己的程序里面来控制任务的切换。

#1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级
#2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 上代码

import   gevent
from   gevent   import   monkey;monkey.patch_all()          #导入gevent模块中的monkey;monkey.patch_all()  
import    time                    #是为了遇到io阻塞直接进行下一任务的方法
import    threading

def   f1():
  print(‘第一次f1‘)
  # print(threading.current_thread().getName())  #这一步是为了证明两协程是一个线程

                       #这一步是看名字,两名字都一样,都是同一个线程名字   
  # gevent.sleep(1)    #这一步是相当于time.sleep的功能的一个io阻塞,
  time.sleep(2)
  print(‘第二次f1‘)

def   f2():
  # print(threading.current_thread().getName())
  print(‘第一次f2‘)
  # gevent.sleep(2)
  time.sleep(2)
  print(‘第二次f2‘)

s = time.time()
g1 = gevent.spawn(f1)         #异步提交了f1任务   是异步,记住是异步 
g2 = gevent.spawn(f2)         #异步提交了f2任务
# g1.join()
# g2.join()
gevent.joinall([g1,g2])        #这是一个小技巧,统一把俩都加上了join,不重要
e = time.time()
print(‘执行时间:‘,e-s)
print(‘主程序任务‘)

#这就是协程了

二:第一种情况的切换。在任务一遇到io情况下,切到任务二去执行,这样就可以利用任务一阻塞的时间完成任务二的计算,效率的提升就在于此。

协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率。为了实现它,我们需要找寻一种可以同时满足以下条件的解决方案

#1. 可以控制多个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行。

#2. 作为1的补充:可以检测io操作,在遇到io操作的情况下才发生切换一个进程里面可以开200个线程,一个线程里面可以开500个协程,,,OK到此,进程,线程,协程都结束了,统称并发编程,下一篇就数据库了,好好学呀大家,好好学习!天天向上!

原文地址:https://www.cnblogs.com/python-lyy/p/10269331.html

时间: 2024-10-08 02:26:11

python协程,线程的其他方法的相关文章

Python核心技术与实战——十五|Python协程

我们在上一章将生成器的时候最后写了,在Python2中生成器还扮演了一个重要的角色——实现Python的协程.那什么是协程呢? 协程 协程是实现并发编程的一种方式.提到并发,肯很多人都会想到多线程/多进程模型,这就是解决并发问题的经典模型之一.在最初的互联网世界中,多线程/多进程就在服务器并发中起到举足轻重的作用. 但是随着互联网的发展,慢慢很多场合都会遇到C10K瓶颈,也就是同时连接到服务器的客户达到1W,于是,很多代码就跑崩溃,因为进程的上下文切换占用了大量的资源,线程也顶不住如此巨大的压力

Python 协程总结

Python 协程总结 理解 协程,又称为微线程,看上去像是子程序,但是它和子程序又不太一样,它在执行的过程中,可以在中断当前的子程序后去执行别的子程序,再返回来执行之前的子程序,但是它的相关信息还是之前的. 优点: 极高的执行效率,因为子程序切换而不是线程切换,没有了线程切换的开销: 不需要多线程的锁机制,因为只有一个线程在执行: 如果要充分利用CPU多核,可以通过使用多进程+协程的方式 使用 打开asyncio的源代码,可以发现asyncio中的需要用到的文件如下: 下面的则是接下来要总结的

00.用 yield 实现 Python 协程

来源:Python与数据分析 链接: https://mp.weixin.qq.com/s/GrU6C-x4K0WBNPYNJBCrMw 什么是协程 引用官方的说法: 协程是一种用户态的轻量级线程,协程的调度完全由用户控制.协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快. 与线程相比,协程更轻量.一个Python线程大概占用8M内

python协程:yield的使用

本文和大家分享的主要是python协程yield相关内容,一起来看看吧,希望对大家学习python有所帮助. 协程定义 协程的底层架构是在pep342 中定义,并在python2.5 实现的. python2.5 中,yield关键字可以在表达式中使用,而且生成器API中增加了 .send(value)方法.生成器可以使用.send(...)方法发送数据,发送的数据会成为生成器函数中yield表达式的值. 协程是指一个过程,这个过程与调用方协作,产出有调用方提供的值.因此,生成器可以作为协程使用

从python协程理解tornado异步

博客原文地址:http://www.v2steve.com/py_tornado_async.html 刚接触tornado时候最疑惑的问题就是tornado.gen.coroutine是怎么实现的.如何在代码中用同步格式实现异步效果.看了几次源码发现其实就是python协程的一个具体应用.下面从生成器开始,说说tornado的异步. python协程 python利用yield关键字实现生成器,yield就像生化危机里的T病毒,被yield感染的函数都不仅仅是函数,而是一个函数生成器.函数生成

python协程函数、递归、匿名函数与内置函数使用、模块与包

目录: 协程函数(yield生成器用法二) 面向过程编程 递归 匿名函数与内置函数的使用 模块 包 常用标准模块之re(正则表达式) 一.协程函数(yield生成器用法二) 1.生成器的语句形式 a.生成器相关python函数.装饰器.迭代器.生成器,我们是如何使用生成器的.一个生成器能暂停执行并返回一个中间的结果这就是 yield 语句的功能 : 返回一个中间值给调用者并暂停执行. 我们的调用方式为yeild 1的方式,此方式又称为生成器的语句形式. 而使用生成器的场景:使用生成器最好的场景就

python协程的实现(greenlet源码分析)

基本上读完了greenlet的源代码,代码不多,就2000行C语言的代码,其中有一部分栈寄存器的修改的代码是由汇编实现的... 一句话来说明greenlet的实现原理:通过栈的复制切换来实现不同协程之间的切换... 那么接下里来具体的来看看greenlet的代码到底是怎么实现的... 好了,先来看看greenlet对象对应的C语言结构体: /** States: stack_stop == NULL && stack_start == NULL: did not start yet sta

python 协程, 异步IO Select 和 selectors 模块 多并发演示

主要内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 selectors 模块 多并发演示 协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开

python协程的理解

一.介绍 什么是并发?并发的本质就是切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制):1.任务发生阻塞2.计算任务时间过长,需要让出cpu给高优先级的程序 协程,又称微线程,是一种用户态的轻量级线程.协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置,当程序中存在大量不需要CPU的操作时(IO),适用于协程.协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/