协程

kotlin 协程 与 android ImageView

荒凉一梦 提交于 2019-12-01 02:58:22
今天因为要给banner的图片添加圆角,使用 Bitmap 转换圆角 用协程去切换线程 在Debug中出现 ThreadException: Only the original thread that Created a view hierarchy can touch its views 不debug时正常显示 猜测原因为: 协程在debug时,当前线程被断点阻塞,自动切换到其他线程中去了 导致不是原始的view历史记录线程操作显示View 解决办法为: 在与UI界面的控件交互的代码 加上 withContext(Dispatchers.Main){  //你的 view 代码   imageView.setImageBitmap(bitmap) } 来源: https://www.cnblogs.com/caosq/p/11649746.html

python中的asyncio模块

て烟熏妆下的殇ゞ 提交于 2019-12-01 00:01:10
asyncio异步IO,能够异步网络操作,并发,协程 1、asyncio的关键字说明 event_loop事件循环:程序开启一个无限循环,把一些函数注册到事件循环上,当满足事件发生的时候,调用相应的协程函数 coroutine协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象,协程对象需要注册到事件循环,由事件循环调用。 task任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含了任务的各种状态 future:代表将来执行或没有执行的任务结果。它和task上没有本质上的区别 async/await关键字:async定义一个协程,await用于挂起阻塞的异步调用接口,在python3.4是使用asyncio.coroutine/yield from 2、定义一个协程 # -*-coding:utf-8 -*- import asyncio async def func(): print("waiting----func------") #这里是一个协程对象,这个时候func()函数并没有执行 coroutine = func() print("coroutine",coroutine) #创建一个循环时间loop loop = asyncio.get_event_loop()

flask 源码解析:上下文(一)

时光毁灭记忆、已成空白 提交于 2019-11-30 19:20:27
文章出处 https://www.cnblogs.com/jackchengcc/archive/2018/11/29/10025949.html 一:什么是上下文    每一段程序都有很多外部变量。只有像Add这种简单的函数才是没有外部变量的。一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行。你为了使他们运行,就要给所有的外部变量一个一个写一些值进去。这些值的集合就叫上下文。   在 flask 中,视图函数需要知道它执行情况的请求信息(请求的 url,参数,方法等)以及应用信息(应用中初始化的数据库等),才能够正确运行。 最直观地做法是把这些信息封装成一个对象,作为参数传递给视图函数 。但是这样的话,所有的视图函数都需要添加对应的参数,即使该函数内部并没有使用到它。flask 的做法是把这些信息作为类似全局变量的东西,视图函数需要的时候,可以使用 from flask import request 获取。 但是这些对象和全局变量不同的是——它们必须是动态的,因为在多线程或者多协程的情况下,每个线程或者协程获取的都是自己独特的对象,不会互相干扰。 二:实现过程    在python多线程中,有threading.local,可以实现多个线程访问某个变量时,每个线程只能看到自己的数据(flask上下文中,每个线程也只能访问自己请求所封装的数据),其内部原理大致为

Golang:线程 和 协程 的区别

做~自己de王妃 提交于 2019-11-30 18:00:57
Golang:线程 和 协程 的区别 目录 前言 协程 协程的特点 第 1 和 第 2 点 特点中的第 3 和 第 4 点 和线程的整体对比 协程 协程,英文名 Coroutine 。但在 Go 语言中,协程的英文名是: gorutine 。它常常被用于进行 多任务 ,即 并发作业 。没错,就是 多线程 作业的那个作业。 虽然在 Go 中,我们不用直接编写线程之类的代码来进行并发,但是 Go 的协程却 依赖于线程 来进行。 协程的特点 这里先直接列出线程的特点,然后从例子中进行解析。 多个协程可由一个或多个线程管理, 协程的调度 发生在其所在的线程中。 可以被调度,调度策略由应用层代码定义,即可被高度自定义实现。 执行效率高。 占用内存少。 上面 第 1 和 第 2 点 我们来看一个例子: func TestGorutine(t *testing.T) { runtime.GOMAXPROCS(1) // 指定最大 P 为 1,从而管理协程最多的线程为 1 个 wg := sync.WaitGroup{} // 控制等待所有协程都执行完再退出程序 wg.Add(2) // 运行一个协程 go func() { fmt.Println(1) fmt.Println(2) fmt.Println(3) wg.Done() }() // 运行第二个协程 go func() { fmt

并发编程之协程

心已入冬 提交于 2019-11-30 17:41:19
一、协程概述 1、什么是协程? 协程也被称为“微线程”,在一个线程中规定某个代码块的执行顺序 。 线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。 2、为什么会有协程?   对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。这样更加节约切换的时间。 3、协程的特点? 不需要多线程的锁机制 因为只有一个线程,不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。 可以利用多核特点 通过多进程 + 协程既可以利用多核又可以发挥协程的高效率。 从技术的角度来说,“协程就是你可以暂停执行的函数” 类似于python中的生成器 4、协程的应用场景 当程序中存在大量不需要CPU的操作时(IO),适用于协程。 二、greenlet、gevent模块 (一)greenlet 上面说了从技术层面上说“协程就是你可以暂停执行的函数”,相当于一个生成器,greenlet是一个用C实现的协程模块: from greenlet import greenlet def test1(): print(9) gr2.switch() #手动切换执行test2 print(22) gr2.switch() #手动切换执行test2

Channel使用技巧

夙愿已清 提交于 2019-11-30 16:42:11
前言 Go协程一般使用channel(通道)通信从而协调/同步他们的工作。合理利用Go协程和channel能帮助我们大大提高程序的性能。本文将介绍一些使用channel的场景及技巧 场景一,使用channel返回运算结果 计算斐波那契数列,在学习递归时候这是个经典问题。现在我们不用递归实现,而是用channel返回计算得出的斐波那契数列。 计算前40个斐波那契数列的值,看下效率 package main import ( "fmt" "time" ) //计算斐波那契数列并写到ch中 func fibonacci(n int, ch chan<- int) { first, second := 1, 1 for i := 0; i < n; i++ { ch <- first first, second = second, first+second } close(ch) } func main() { ch := make(chan int, 40) i := 0 start := time.Now() go fibonacci(cap(ch), ch) for result := range ch { fmt.Printf("fibonacci(%d) is: %d\n", i, result) i++ } end := time.Now() delta := end.Sub

协程:gevent

╄→гoц情女王★ 提交于 2019-11-30 16:11:58
阅读目录 一 引子 二 协程介绍 三 Greenlet模块 四 Gevent模块 引子   之前我们学习了线程、进程的概念,了解了在操作系统中 进程是资源分配的最小单位,线程是CPU调度的最小单位。 按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。   随着我们对于效率的追求不断提高, 基于单线程来实现并发 又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。   为此我们需要先回顾下并发的本质:切换+保存状态   cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长       ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态    一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。   为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: #1 yiled可以保存状态

Python连载40-协程定义及状态、send语句、yield用法

独自空忆成欢 提交于 2019-11-30 15:16:21
一、协程 1.历史进程: (1)3.4引入协程,用yield来实现 (2)3.5引入协程语法 (3)实现协程比较好的包有asyncio,tornado,gevent 2.定义:协程是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序 3.从技术角度讲,协程就是一个可以暂停执行的函数,或者干脆把协程理解为一个生成器 4.协程对资源的消耗很小,要比多进程消耗的资源小多了,因此多并发下,协程更节省资源。 5.协程的实现 (1)yield返回;(2)send调用 (3)协程的三个状态: inspect.geigeneratorstate(...)函数确定,该函数会返回下面的字符串中的一个: GEN_CREATED:等待开始执行 GEN_RUNNING:解释器正在执行 GEN_SUSPENED:在yield表达式处暂停 GEN_CLOSED:执行结束 next预激(prime) 6.举例子(注意里面的注释) def simple_coroutine(): print("->start") x = yield#这个函数执行到这里停止了,等待着给它赋值,也就是后面的send语句 print("->recived",x) #主线程 sc = simple_coroutine() print(1111) #可以使用sc.send(None),效果一样 next

基于协程的并发

旧巷老猫 提交于 2019-11-30 14:55:50
基于协程的并发 一、什么是协程 协程是单线程下的并发,又称微线程,纤程。协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。我们需要知道的是: #1. python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行) #2. 单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(非io操作的切换与效率无关) 协程的特点是: 必须在只有一个单线程里实现并发; 修改共享数据不需加锁; 用户程序里自己保存多个控制流的上下文栈 一个协程遇到IO操作自动切换到其它协程 二、Greenlet 如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用yield生成器的方式过于麻烦,而使用greenlet模块可以非常简单地实现这20个任务直接的切换。 #安装 pip3 install greenlet from greenlet import greenlet def test1(): print(12) gr2.switch() #切换到gr2 print(34) gr2.switch() #切换到gr2 def test2(): print(56) gr1.switch() #切换到gr1 print(78) gr1 = greenlet(test1) gr2 =

循环开协程情况分析

流过昼夜 提交于 2019-11-30 09:47:01
循环开协程情况分析 代码 package main import( "fmt" "runtime" "sync" ) //for循环只是用来创建协程而已,当协程创建完成之后,就不再受for控制 func main(){ runtime.GOMAXPROCS(1) wg := sync.WaitGroup{} wg.Add(60) for a:=0;a<10;a++{ fmt.Println("这里先运行",a) go func(){ defer wg.Done() fmt.Printf("a的地址: %p , %v \n",&a,a) }() } for i:=10;i<20;i++{ go func(i int){ defer wg.Done() fmt.Printf(" i的地址: %p , %v \n",&i,i) }(i) } wg.Wait() fmt.Println("想看运行结果") } 输出结果 这里先运行 0 这里先运行 1 这里先运行 2 这里先运行 3 这里先运行 4 这里先运行 5 这里先运行 6 这里先运行 7 这里先运行 8 这里先运行 9 i的地址: 0xc000010158 , 19 a的地址: 0xc000010038 , 10 a的地址: 0xc000010038 , 10 a的地址: 0xc000010038 , 10 a的地址: