首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么使用协程阻塞线程时会执行代码?

协程是一种轻量级的线程,可以在单个线程中实现并发执行。与传统的线程相比,协程具有以下优势:

  1. 轻量级:协程是在用户空间中实现的,不需要操作系统的线程切换,因此占用的资源更少,创建和销毁的开销更小。
  2. 高效性:由于协程在单个线程中执行,避免了线程切换的开销,因此可以更高效地利用计算资源。
  3. 灵活性:协程可以通过挂起和恢复的方式来实现协作式多任务处理,可以在任意时刻挂起当前协程并切换到其他协程执行,从而实现任务的切换和调度。
  4. 简化编程模型:使用协程可以将复杂的异步编程模型简化为顺序的同步代码,提高代码的可读性和可维护性。

当使用协程阻塞线程时,实际上是通过挂起当前协程来释放线程的执行权,让线程可以执行其他任务。协程的挂起和恢复是由协程调度器来管理的,调度器会根据一定的策略来决定何时挂起当前协程并切换到其他协程执行。

在协程阻塞线程时,执行的代码是由协程调度器来控制的。当一个协程遇到阻塞操作(如IO操作)时,协程调度器会将该协程挂起,并切换到其他可执行的协程上。当阻塞操作完成后,协程调度器会恢复该协程的执行,继续执行后续的代码。

使用协程阻塞线程的好处是可以充分利用线程的并发能力,提高系统的吞吐量和响应性能。由于协程的轻量级和高效性,可以创建大量的协程来处理并发任务,而不会造成线程的资源浪费和性能下降。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云容器服务(Tencent Kubernetes Engine,TKE):https://cloud.tencent.com/product/tke
  • 腾讯云函数计算(Tencent Cloud Serverless Cloud Function,SCF):https://cloud.tencent.com/product/scf
  • 腾讯云云原生数据库 TDSQL-C:https://cloud.tencent.com/product/tdsqlc
  • 腾讯云云服务器(Tencent Cloud Virtual Machine,CVM):https://cloud.tencent.com/product/cvm
  • 腾讯云对象存储(Tencent Cloud Object Storage,COS):https://cloud.tencent.com/product/cos
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Kotlin 的挂起和恢复 ② ( 挂起 和 线程阻塞 对比 )

文章目录 一、挂起 和 线程阻塞 对比 1、挂起 2、线程阻塞 3、挂起和阻塞对 UI 的影响 4、挂起分析 一、挂起 和 线程阻塞 对比 ---- 挂起是中的概念 , 只能在使用...; 阻塞线程中的概念 , 可以在主线程和子线程使用 ; 1、挂起 挂起 操作 : 在使用 delay 函数 , 挂起 20 秒时间 , 然后 20 秒后更新 UI ; delay...Log.i("MainActivity", "GlobalScope : 主线程更新 UI") } 2、线程阻塞线程 阻塞 操作 : 在主线程使用 Thread.sleep 函数 , 阻塞 20...主线程更新 UI") 3、挂起和阻塞对 UI 的影响 挂起 操作 不会出现 阻塞 UI 刷新的情况 , 挂起的 20 秒不影响 UI 刷新显示 ; 但是如果将主线程阻塞 , UI 不再刷新 , 会出现..., ANR 崩溃异常 ; 4、挂起分析 中有挂起操作 , 会将挂起点的状态保存 , 同时停止执行 , 等待挂起函数执行完毕后 , 继续执行 ; 相当于阻塞的是 , 不会阻塞线程 ;

1.7K20

什么是_什么时候使用线程

你想下,前面几种情况自然没有什么话可说,但是如果是在阻塞等待,是不是就浪费了。 其实阻塞的话我们的程序还有其他可执行的地方可以执行,不一定要傻傻的等! 所以就有了线程。...这种线程其实也就解决了当一个进程中,某个正在执行线程遇到阻塞,我们可以调度另外一个可运行的线程来跑,但是还是在同一个进程里,所以没有了进程切换。...你可以使用下面的代码来测试: <?...3)堆栈 鸟哥文中还有一个堆栈的例子。 我们上面说过了,如果在函数中使用了yield,就不能当做函数使用。 所以你在一个函数中嵌套另外一个函数: <?...所以就需要堆栈。 不过没关系,我们改一改我们刚刚的代码。 把Task中的初始化方法改下,因为我们在运行一个Task的时候,我们要分析出他包含了哪些子,然后将子用一个堆栈保存。

67020

并发-并行-阻塞-非阻塞-异步-同步-长连接-短连接-进程-线程-

进程、线程 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。...线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。 ,又称微线程,纤。英文名Coroutine。是属于线程的。...程序是在线程里面跑的,因此又称微线程和纤等。没有线程的上下文切换消耗。的调度切换是用户(程序员)手动切换的,因此更加灵活,因此又叫用户空间线程。...由于是用户调度的,所以不会出现执行一半的代码片段被强制中断了,因此无需原子操作锁。 线程和进程各自有什么区别和优劣呢? 进程是资源分配的最小单位,线程是程序执行的最小单位。...而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

69210

Lua使用实现多线程

能够实现一种协作式多线程。每个协都等价于一个线程。一对yield-resume可以将执行权在不同线程之间切换。 不过,与普通的多线程的不同,是非抢占的。...当一个正在运作时,是无法从外部停止它的。只有当显式地要求时它才会挂起执行。对于有些应用而言,这并没有问题,而对于另外一些应用则不行。当不存在抢占时,编程简单得多。...不过,对于非抢占式多线程来说,只要有一个线程调用了阻塞操作,整个程序在该操作完成前都会阻塞。对于很多应用来说,这种行为是无法接受的,而这也正是导致许多程序员不把看作传统多线程的一种实现的原因。...在用重写程序前,我们先把之前下载的代码重写成一个函数。...这样,会导致版的实现比串行版实现耗费多达3倍的CPU时间。 为了避免这样的情况,可以使用LuaSocket中的函数select,该函数允许程序阻塞直到一组套接字的状态发生改变。

1.6K40

破解 Kotlin 番外篇(1) - 为什么被称为『轻量级线程』?

Continuation 携带了继续执行所需要的上下文,同时它自己又是挂起点,因为待会儿恢复执行的时候只需要执行它回调的函数体就可以了。...再强调一下,这段代码不需要运行在体内,或者其他的 suspend 函数中。现在请大家仔细想想,为什么官方要求 suspend 函数一定要运行在体内或者其他 suspend 函数中呢?...线程除了包含内核线程本身执行代码能力的含义以外,通常也被赋予了逻辑任务的概念,所以是一种轻量级的『线程』的说法,更多描述的是它的使用场景,这句话也许这样说更贴切一些: 更像一种轻量级的『线程』。...你写的可是线程啊? 对啊,用了 NIO 以后,本身就可以减少线程使用,没错的。可是呢?...我更愿意把作为更贴近业务逻辑甚至人类思考层面的一种抽象,这个抽象层次其实已经比线程更高了。线程可以让我们的程序并发的跑,可以让并发程序跑得看起来更美好。 线程本身就可以,为什么要用呢?

1.9K20

为什么 Java 坚持多线程不选择

NIO配合实现非阻塞的编程,提高系统的吞吐 使用起来更加舒服顺畅(async+await,跑起来是异步的,但写起来感觉上是同步的) 我们分开来讲下。...这个问题在Java里通过线程池得到了很好的解决。你会发现即便你用vert.x或者kotlin的,归根到底也是要靠线程池工作的。...kotlin利用这个机制来构建多个不同的scope。这看起来似乎会更灵活一点。 然后是线程的切换开销。线程的切换实际上只会发生在那些“活跃”的线程上。...最后说一句,多线程容易出bug主要因为: “抢占“式的线程切换 —— 你无法确定两个线程访问数据的顺序,一切都很随机 “同步“不可组装 —— 同步的代码组装起来也不同步,必须加个更大的同步块 能不能避免容易出...如果底层用的还是线程池,两个协还是通过共享内存通讯,那么多线程该出什么bug,多照样出。

1.6K20

代码详解Python多线程、多进程、

本文就通过代码讲解如何使用多进程、多线程来提升爬取速度。注意:我们不深入介绍理论和原理,一切都在代码中。 二、同步 首先我们写一个简化的爬虫,对各个功能细分,有意识进行函数式编程。...在执行程序时每个时间刻度上只会存在一个线程,因此多线程实际上提高了进程的使用率从而提高了CPU的使用率 实现多线程的库有很多,这里用concurrent.futures中的ThreadPoolExecutor...多进程和多线程确实能够达到加速的目的,但如果遇到IO阻塞会出现线程或者进程的浪费,因此有一个更好的方法…… 五、异步非阻塞 +回调配合动态协作就可以达到异步非阻塞的目的,本质只用了一个线程,所以很大程度利用了资源...实现异步非阻塞经典是利用asyncio库+yield,为了方便利用逐渐出现了更上层的封装 aiohttp,要想更好的理解异步非阻塞最好还是深入了解asyncio库。...而gevent是一个非常方便实现的库 import requests > from gevent import monkey # 猴子补丁是协作运行的灵魂 > monkey.patch_all()

1.4K30

Python使用monkey.patch_all()解决阻塞问题

直接参考以下实例,采用访问三个网站 由于IO操作非常耗时,程序经常会处于等待状态 比如请求多个网页有时候需要等待,gevent可以自动切换 遇到阻塞自动切换,程序启动时执行monkey.patch_all...()解决 # 由于IO操作非常耗时,程序经常会处于等待状态 # 比如请求多个网页有时候需要等待,gevent可以自动切换 # 遇到阻塞自动切换,程序启动时执行monkey.patch_all(..._main__': urls = ['https://github.com/', 'https://blog.csdn.net/', 'https://bbs.csdn.net/'] # 定义方法...greenlets = [gevent.spawn(run_task, url) for url in urls] # 添加任务,并且启动运行 gevent.joinall(greenlets...) # 查看运行结果可以发现,三个是同时触发的,但是结束顺序不同 # 网页请求的时间不同,故结束顺序不同 # 但是该程序其实只有一个线程 输出结果 Visit — https://github.com

1.3K20

【Kotlin 取消 ③ ( finally 释放资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的任务 | 构造超时取消的任务 )

文章目录 一、释放资源 二、使用 use 函数执行 Closeable 对象释放资源操作 三、使用 withContext(NonCancellable) 构造无法取消的任务 四、使用 withTimeoutOrNull...函数构造超时取消的任务 一、释放资源 ---- 如果 中途取消 , 期间需要 释放占有的资源 ; 如果执行任务中 , 需要 执行 关闭文件 , 输入输出流 等操作 , 推荐使用...22:06:06.510 I 退出作用域 二、使用 use 函数执行 Closeable 对象释放资源操作 ---- 使用 use 函数 可以在 程序结束时 , 执行实现了 Closeable...withContext(NonCancellable) 构造无法取消的任务 ---- 如果在 finally 中需要使用 suspend 挂起函数 , 则 挂起函数以及之后的代码将不会被执行 ;...代码块的代码肯定会执行 , 但是如果 finally 中 delay 挂起函数以及之后的代码将不会被执行 ; 使用 withContext(NonCancellable) {} 代码块 , 可以构造一个无法取消的任务

1.3K10

使用阻塞队列实现线程同步_线程可以并行执行

,如果系统只有一个 CPU,则它根本不可能真正同时进行一个以上的线程,它只能把 CPU 运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状态.这种方式我们称之为并发...当一个 CPU 执行一个线程时,另一个 CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行,这种方式我们称之为并行(Parallel)。...二、进程与线程 1.名称解释 进程:程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础 线程:有时被称为轻量级进程,是程序执行流的最小单元。...1.名词解释 阻塞:是指调用结果返回之前,当前线程会被挂起。...调用线程只有在得到结果之后才会返回 非阻塞:调用指在不能立刻得到结果之前,该调用不会阻塞当前线程 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态 2.举个例子 阻塞:你去书店买书,立即买到了

47430

在 Android 开发中使用 | 代码实战

使用解决实际编码问题 前两篇文章主要是介绍了如何使用来简化代码,在 Android 上保证主线程安全,避免任务泄漏。...以此为背景,我们认为使用是在处理后台任务和简化 Android 回调代码的绝佳方案。 目前为止,我们主要集中在介绍是什么,以及如何管理它们,本文我们将介绍如何使用来完成一些实际任务。...因为这个仓库中存储的商品很多,所以对它们进行排序要花费将近 1 秒钟,因此我们需要使用来避免阻塞线程。 在应用中,所有的数据都会存储到 Room 数据库中。...所以,如果您要对执行结果做一些比较耗时的操作,比如对列表内容进行转换,您要确保这个操作不会阻塞线程。 注意: Room 使用了自己的调度器在后台线程上进行查询操作。...ViewModel 在主线程上启动了,一旦有结果后就结束执行; Repository 提供了保证主线程安全的挂起函数; 数据库和网络层提供了保证主线程安全的挂起函数。

1.1K10

Kotlin | 从线程,你是否还存在 上的使用疑问

Kotlin | 从线程,你是否还存在理解上的疑问 引言 在2022的今天,对于一个 Android 开发同学,如果你使用 Kotlin 作为主要开发语言,那么是必不可缺的 异步框架 。...接口回调 如果用 回调 去做,免除 阻塞线程 ,又是这样的写法: 定义一个接口,任务A开始执行,在这里等,等另一边任务B完成后,再调用任务A接口方法即可完成唤醒。... 解析 在 Android 官网中,对的描述如下: 是一种并发设计模式,您可以在 Android 平台上使用它来简化 异步执行代码。...综合对比上述的解法来看: 线程写法:我们需要调用 await ,这将使得正在运行的线程[阻塞],对我们的性能造成了影响; 回调写法:我们不再阻塞线程,但我们逻辑更复杂化,如果存在多个回调,这将提高阅读成本...前者在执行任务B时,我们切换到了 IO ,并最终将状态返回,接下来,我们判断,如果获得的state是我们想要的写法,就继续操作; 后者在执行任务B时,利用了suspendCoroutine 函数,我们可以将一些回调的代码借此改为的同步写法

1.3K20

Golang 线程进程 区别以及 GMP 详解

**** 线程一样共享堆,不共享栈,是由程序员在代码中显示调度。(用户态线程)是对内核透明的, 也就是系统完全不知道有的存在, 完全由用户自己的程序进行调度。...当阻塞时,例如通过调用阻塞系统调用,运行时会自动将同一操作系统线程上的其他移动到不同的可运行线程,这样它们就不会被阻塞。 程序员看不到这些,这就是重点。...但是必须要区分的一点是,是用用户态的,进程跟线程都是内核态,这点非常重要,这也是为什么高效的原因。...当阻塞时,例如通过调用阻塞系统调用,运行时会自动将同一操作系统线程上的其他移动到不同的可运行线程,这样它们就不会被阻塞。 也就是说,执行是需要通过线程来先实现的。...缺点: - 某个程序用不了硬件的多核加速能力 - 一旦某阻塞,造成线程阻塞,本进程的其他都无法执行了,根本就没有并发的能力了。 [!

47520

Kotlin | 是什么?

很高兴,你终于追寻这个问题了,也许你正感到迷茫,各路大神对的理解不一,有人说它是线程框架,有人说它比线程更轻,希望我这篇博文可以帮你从另一个角度简单理解。...,但对于使用角度的来说,努力打造一个 "同步方式,异步编程的" 思想,作为开发者来说,我们可以更懒了,切换线程,withContext即可,带来了开发上的舒适,但这种舒适是基于 Kotlin 的语法...观察上面的打印日志,我们不难发现,在调用 delay 函数时,线程并没有停下,相对来说,只是我们的代码块被挂起,等待恢复。只有前面的挂起函数执行结束,我们的代码块才能继续执行。...所谓的非阻塞,其实就是切换了线程,观察打印日志变化,我们可以发现,当我们直接 GlobalScope.launch 启动一个时,此时运行的线程为默认的线程,所以被称为非阻塞的实现方式。...挂起函数为什么只能在挂起函数中使用呢? 因为普通函数参数并没有带 Continuation啊,相当于没有挂起点,编译器无法判断,所以此时会报错。 为什么test 的suspend 标志是黑的?

54710

源码中的原子操作为什么使用 AtomicReferenceFieldUpdater?

概要 AtomicReferenceFieldUpdater 比 AtomicReference 用起来稍微有些麻烦,可大佬为什么更喜欢它?...正文 SafeContinuation 是挂起点定义时经常需要用到的一个用来保证结果正常返回的类,它当中有个成员 result,这个成员由于可能被多个线程访问,因此存在保证线程安全的要求,不过奇怪的是,...SafeContinuation 的开发者选择使用 AtomicReferenceFieldUpdater 来原子地更新这个成员,而没有使用更直接更便捷的 AtomicReference 类作为 result...,前者约 103B,后者约 29B,对于后者来说,用以保证修改原子性的 valueUpdater 是个共享的对象,因此对于可能创建较多实例的场景,应当考虑优先使用 AtomicReferenceFieldUpdater...而 SafeContinuation 恰好就是一个经常被创建的类型,因此使用 AtomicReferenceFieldUpdater 能极大的减少内存压力。 ----

58520

Go 为什么比进程和线程占用的系统资源低?

进程和线程都是 CPU 的一个执行单元,在内核态切换,切换成本较高。 是用户态的一个伪执行单元,在用户态切换执行流程,切换成本较低。...02 切换执行单元的成本 我们通过介绍线程和协的切换流程,讲述为什么在内核态切换的成本较高,而在用户态切换的成本较低?...在编写代码时,我们为了可以让程序被分配到更多的 CPU 资源,可以多创建一些线程,用于提升程序运行的效率。需要注意的是,线程并不是创建越多越好。...用户态切换 - 因为通过创建线程执行单元),为程序争取更多的 CPU 资源,在线程切换时也会浪费 CPU 资源(时间成本),所以可以将执行单元不再在内核态运行,改为在用户态运行,也就是。...04 总结 本文我们主要介绍为什么 Go 比进程和线程占用的系统资源低,通过进程、线程的 CPU 资源和内存占用的比较,发现无论是在切换时消耗的 CPU 资源(时间片),还是内存占用,Go

38650

Go 并发实战--浅析 一

goroutine实际上就是为什么叫做go呢,因为go在runtime、系统调用方面对goroutine调度进行了封装和处理,也就是说go在语言层面实现对于go的支持:使用go 关键字就可以了...最主要的是不担心间切换、或者打满或者夯死。 关于这类知识,感觉先说原理再说使用会比较理解,后面就先来看下go的实现原理。...image.png goroutine goroutine 就是我们使用的go使用go 关键字就可以了:go func1(),所有的go都由runtime管理(新建、恢复、停止、休眠,其中执行异步操作时...(用于防止GC扫描) machine machine指的是系统线程,他是go代码的具体执行者,它执行: 1、goroutine需要执行代码(需要process) 2、原生代码(不需要process...自旋(spinning): 正在取goroutine 执行态(running): 在执行代码或者阻塞的syscall 休眠中 : 当上个任务执行完,但goroutine队列中无任务时 process

71620

Kotlin系列(一)

言归正传,我们在学习一个新东西的时候,如果连这个东西"是什么"都回答不了,那么自然很难进入知识获取阶段的"为什么"和"怎么办"这两个后续环节了。因此,我们首先得知道的定义。   ...线程在等待某种资源或者等待I/O操作完成时,会被阻塞,并且在阻塞的期间还一直霸占着CPU资源。...而的挂起是不会阻塞线程的,运行在这个线程上的其他还会照常执行,并且挂起时会主动释放自己的CPU资源。...,在恢复执行时会执行该函数 println("运行结束,结果为:$result") } })   标准库提供了一个createCoroutine函数,...我们可以使用它来创建,但是创建的不会立马执行

19310

万字长文带你深入理解|业界设计和实现的决策分析

但是当这段代码执行于libco的中时,被hook后的结果isNonBlock居然是true!...锁、读写锁 在任何C++库的使用中,都应该慎重使用或禁用线程锁,比如下面的代码 A首先被调度,加锁后调用sleep导致当前挂起,注意此时mtx已然是被锁定的。...然后B被调度,要等待mtx被解锁才能继续执行下去,由于mtx是线程锁,会阻塞调度线程A再也不会有机会被调度,从而形成死锁。...然后B被调度,要等待mtx被解锁才能继续执行下去,由于mtx是锁,锁在等待时会挂起当前而不是阻塞线程A在sleep时间结束后会被唤醒并被调度,A退出foo函数时会解锁,解锁的行为又会唤醒...libgo提供了一个宏:co_await,来辅助用户完成线程池与的交互。 在使用 可以把func投递到线程池中,并且挂起当前,直到func完成后会被唤醒,继续执行下去。

37410
领券