Coroutine 基础

Lua基础之coroutine(协程) 概括:1.创建协程 2.coroutine的函数 3.coroutine的基本流程 4.yield对coroutine流程的干预 5.resume, function()以及yield之间的参数传递和返回值传递 阅读详情

Coroutine 基础

我们将介绍协程的基本概念。

第一个协程程序

我们把下面的代码跑起来:

import kotlinx.coroutines.*

fun main() {
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
        println("World!") // print after delay
    }
    println("Hello,") // main thread continues while coroutine is delayed
    Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}  

我们可以看到输出:

Hello,
World!

本质上,协程是轻量级的线程。可以用协程构造器 launch 来启动协程,使其运行在 CoroutineScope 环境上下文中。我们在 GlobalScope 启动一个新的协程,它的生命周期仅受整个应用生命周期的限制。

我们可以尝试把 GlobalScope.launch{...} 替换为 thread{...} ,把 delay(...) 替换为 Thread.sleep(...) 。我们可以得到相同的结果。

假如我们仅仅把 GlobalScope.launch 替换为 thread ,编译器将会报错:

Error: Kotlin: Suspend functions are only allowed to be called from a coroutine or another suspend function

这是因为 delay 是特殊的挂起函数,它不会阻塞线程,但是这种特殊的函数只能在协程环境中调用。

桥接阻塞和非阻塞

上面那个例子混合非阻塞函数 delay(...) 和阻塞函数 Thread.sleep(...) 在同一段代码中,我们不能比较清晰的看出哪个是阻塞的,哪个是非阻塞的。我们让它运行在 runBlocking 协程中:

import kotlinx.coroutines.*

fun main() { 
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L)
        println("World!")
    }
    println("Hello,") // main thread continues here immediately
    runBlocking {     // but this expression blocks the main thread
        delay(2000L)  // ... while we delay for 2 seconds to keep JVM alive
    } 
}  

这个结果是相同的,但是整段代码只使用了非阻塞函数 delay(),主线程调用 runBlocking,将会阻塞,知道 runBlocking 协程内部执完成。

我们可以换种更常见的方式来编写:

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> { // start main coroutine
    GlobalScope.launch { // launch new coroutine in background and continue
        delay(1000L)
        println("World!")
    }
    println("Hello,") // main coroutine continues here immediately
    delay(2000L)      // delaying for 2 seconds to keep JVM alive
}

上面的例子中,我们明确指定了返回值,Unit。

等待job完成

使用延时函数来等待协程的完成不是一个好的实现。让我们使用一种非阻塞的方法明确的等待协程的启动和执行完成。

import kotlinx.coroutines.*

fun main() = runBlocking {
//sampleStart
    val job = GlobalScope.launch { // launch new coroutine and keep a reference to its Job
        delay(1000L)
        println("World!")
    }
    println("Hello,")
    job.join() // wait until child coroutine completes
//sampleEnd    
}  

现在,这个执行结果是一样的,但我们的代码更加的合理。

结构化并发

在实际应用中我们还有其他要考虑的。我们使用 GlobalScope.launch 创建了协程,虽然它是轻量级的,但是它还是会消耗内存资源。如果我们忘记引用了,我们新启动的协程还是会在运行。如果我们的协程里执行了需要比较长时间的操作,(比如等待很长时间),或者我们启动了很多的协程,这将会造成内存泄漏。手动的保持每个协程的引用是易于出错的处理的方式。

我们有更合理的解决方法。我们不使用全局的 GlobalScope 协程启动构造器,我们仅在特定的上下文函数中启动。

在我们的例子中,我们使用了 runBlocking 协程构造器,每一个协程构造器,都将会生成一个上下文环境实例 CoroutineScope。我们可以在该上下文环境实例中启动一个新的协程,然后就不能明确的使用 join 等方法了。因为外层的协程函数不会先结束,除非在它上下文环境中启动的所有的协程都已经执行完成。因此,我们的例子可以更加简洁:

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { // launch new coroutine in the scope of runBlocking
        delay(1000L)
        println("World!")
    }
    println("Hello,")
}
上下文构造器

此外,有不同的构造器提供协程上下文环境,我们可以使用 coroutineScope 构造器来声明自己的上下文环境。它将会新构建一个等待所有内部协程完成的上下文环境。和 runBlocking 主要的不同是,它在等待的时候并不阻塞当前线程。

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    launch { 
        delay(200L)
        println("Task from runBlocking")
    }
    
    coroutineScope { // Creates a new coroutine scope
        launch {
            delay(500L) 
            println("Task from nested launch")
        }
    
        delay(100L)
        println("Task from coroutine scope") // This line will be printed before nested launch
    }
    
    println("Coroutine scope is over") // This line is not printed until nested launch completes
}
提取函数重构

我们把 launch{...} 里边的代码块提取出来,如果使用IDE重构函数方式的化,我们可以看到 suspend 修饰符已经被添加在函数前边。挂起函数可以像常规函数一样在协程上下文中使用。但它具有的特有的特性是,它能够在协程上下文中挂起,然后在某个时刻恢复到原来的执行点继续执行。

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch { doWorld() }
    println("Hello,")
}

// this is your first suspending function
suspend fun doWorld() {
    delay(1000L)
    println("World!")
}

不建议在提取的方法中再调用协程构造器启动另一个协程上下文环境,因为这样使得结构不清晰。

协程是轻量化的
import kotlinx.coroutines.*

fun main() = runBlocking {
    repeat(100_000) { // launch a lot of coroutines
        launch {
            delay(1000L)
            print(".")
        }
    }
}

我们启动了10万个协程,每个协程中延时一秒后打印一个 . ,如果我们换成线程的话,很可能抛出内存溢出错误。?

#####全局上下文的协程想守护线程

我们使用 GlobalScope 每一秒打印一次 I'm sleeping , 然后在主线程中延时,然后返回。

import kotlinx.coroutines.*

fun main() = runBlocking {
//sampleStart
    GlobalScope.launch {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
    delay(1300L) // just quit after delay
//sampleEnd    
}

我们可以看到打印了三行:

I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...

用 GlobalScope 启动的协程并不保存进程的存活,它们和守护线程相似。

Lua基础之协同程序(coroutine) Lua 协同程序(coroutine) 什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协 阅读详情

相关推荐

ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT)

ESP32 STA AP模式下,设备连接 ESP的AP 后无法上网,无法访问域名上网(或者Failed to enable NAPT)1.可能是ESP STA模式未成功连接到路由器,确保 STA 成功连接到外部网络。2.检查 STA 和 AP 的网络配置是否正确,避免子网冲突。3.ESP32的NAPT功能未正确启用,确保 menuconfig 中已启用 IP_NAPT。4.DNS服务器未正确配置。

qq_34885669的博客 1539

Kotlin协程(Coroutine)中关于yield的解释

如果你在关注kotlin并且也在关注Coroutine 那么你肯定在官网上看到了 这样的代码: val job = launch { val child = launch { try { delay(Long.MAX_VALUE) } finally { println("Child is cancelled...

weixin_42215792的博客 6649

Android11,无障碍服务模拟多手势使用dispatchGesture时总是onCancelled

AccessibilityService的dispatchGesture去模拟多手势,总是onCancelled的一种解决办法

m0_49953943的博客 2102

Lua之coroutine基础

转自http://blog.youkuaiyun.com/wusheng520/article/details/7954666 一、基本环境: Microsoft Windows XP/Service Pack 2 Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio 二、 coroutine的接口: (1) co

zhukangle的博客 424

MACS2软件进行Peak calling

MACS2可以检出ChIP-Seq,ATAC-seq 以及 MeRIP-seq (RNA甲基化测序) 等富集的序列。peaks calling 有不同的方法,MACS2是最常用的call peaks工具。 MACS全称Model-based Analysis of ChIP-Seq,最初的设计是用来鉴定转录因子的结合位点,但是它也可以用于其他类型的富集方式测序。usage: macs2 [-h] [--version] {callpeak,bdgpeakcall,bdgbroadca

qq_27390023的博客 3789

三、分区配置

rk3566/rk3568 修改分区

暮云星影的博客 514

Ceph OSD 内部架构深度解析:进程模型、双 Messenger、工作队列与 PG 机制

本文以 [doc/dev/osd_internals/osd_overview.rst](https://link.gitcode.com/i/b3f3f83aa392b6d121b2c922b3461bc9) 为骨架,系统拆解 Ceph 分布式存储中 OSD(Object Storage Daemon)的核心内部结构:OSD 在 CRUSH 层级中的定位、双 Messenger 的网络模型、Di

gitblog_00145的博客 978

深度学习框架对比:AI开发如何选择

你是否遇到过这样的困惑:想做一个图像分类模型,朋友推荐PyTorch;公司要部署智能客服,同事说用TensorFlow;想快速验证想法,学长又提到Keras……深度学习框架种类繁多,功能重叠却各有侧重。本文将覆盖主流框架(PyTorch/TensorFlow/Keras/JAX/MXNet等),从开发者真实需求出发,总结选择框架的核心维度。本文将按照“认识框架→对比特性→实战选择”的逻辑展开:先通过生活比喻理解各框架特点,再用代码对比核心功能,最后结合真实场景给出选择建议。动态计算图。

AI 领航者的博客 1162

Kotlin 协程基础Coroutine

Kotlin 协程基础Coroutine [kəruː’tiːn] 需要了解的概念,类 1.协程与线程的区别 本质上,协程是轻量级的线程 一个线程中可以有N个协程。协程中也可以有N个子协程。 2.Dispatchers类 -调度器,指定协程运行在哪个线程中 @JvmStatic //与IO共享线程池,区别在于Default限制了最大并发数,最少2个,最大为cpu的核数 public actual val Default: CoroutineDispatcher = createDefaultDispatch

importSUC的专栏 635

数据资产可视化分析:PowerBI在大数据管理中的实战

目的:帮你搞懂“为什么数据资产需要可视化?”“PowerBI能帮企业解决什么问题?”,并掌握用PowerBI做大数据可视化的实战技巧。范围:覆盖数据资产定义、可视化分析原理、PowerBI核心功能(数据连接、建模、可视化)、零售企业实战案例,以及未来趋势与挑战。背景:为什么企业的数据像乱堆的玩具?核心概念:数据资产、可视化分析、PowerBI分别是什么?它们怎么配合?实战步骤:用PowerBI帮零售企业整理“销售玩具箱”,做出能指导决策的仪表盘;应用场景:不同部门怎么用这个“整理好的玩具箱”?

2501_92132293的博客 906

3、★☛基于STM32的手机通过wifi控LED灯√♠★

3、基于STM32的手机通过wifi控LED灯 文章目录3、基于STM32的手机通过wifi控LED灯1、Introduce介绍1.1、课题背景及其意义1.2、 国内外的研究状况2、方案的设计2.1、控制方案的确定2.2、控制方式的选择2.2.1、 单片机芯片的选择方案一方案二方案三方案四2.2.2、无线遥控模块的选择方案一方案二方案三3、硬件电路的设计3.1、系统的功能分析及体系结构设计3.1.1、系统功能分析3.1.2、系统总体结构3.2、模块电路的设计3.2.1、 STM32单片机核心电路设计3.2.

行走的皮卡丘 2962

Unity3D 基础——Coroutine 协同程序

Coroutine 称为协同程序或者协程,协同程序可以和主程序并行运行,和多线程有些类似。协同程序可以用来实现让一段程序等待一段时间后继续运行的效果。例如,执行步骤1,等待3秒;执行步骤2,等待某个条件为 true;执行步骤3......在Unity3D 中,使 MonoBehaviour.StartCoroutine 方法即可开启一个协同程序,也就是说该方法必须在 MonoBehaviour 类或继承于 MonoBehaviour 的类中调用。

神枪达的博客 649

华为OD机考双机位C卷 - 区间交集(Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 区间交集

算法大师! 1136

Lua coroutine基础

Lua

影子 433

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

kotlin coroutine文档:基础

协程基础 这部分讲述协程基础概念。 第一个协程 运行如下代码: import kotlinx.coroutines.* fun main() { GlobalScope.launch { // 在后台启动新协程,然后继续运行 delay(1000L) // 非阻塞式延时1秒(默认时间单位是毫秒) println(&amp;quot;World!&amp;quot;) // 在延时后打印 ...

tigershin的专栏 344

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

关于 Unity 协程(Coroutine)基础知识

本文介绍了Unity中协程(Coroutine)的基本概念和使用方法。协程是一种可以暂停执行并在指定时间后继续的特殊函数,与普通函数的区别在于它可以被中断而不会阻塞主线程。文章通过实例演示了如何使用协程实现延迟3秒改变立方体颜色的功能,详细解析了协程的关键代码,并介绍了常用的yield指令。协程是Unity处理异步和时间相关任务的重要工具,掌握协程对游戏开发至关重要。

qq_14911629的博客 628

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

[Unity基础]对Coroutine的一些理解

相关链接: http://dsqiu.iteye.com/blog/2029701 http://www.cocos2dev.com/?p=496 http://7dot9.com/?p=605 http://7dot9.com/?paged=2 开启与关闭协程: using UnityEngine; using System.Collections; p

宏哥的博客 1933

(转) Lua之coroutine基础

感觉是比较老的文章了,但是对于我这种新手还是很有帮助的v_v 一、基本环境: Microsoft Windows XP/Service Pack 2 Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio 二、 coroutine的接口: (1) coroutine.create() (2) coroutine.resume() (3) corou...

个人小站:hjwu.cc 114

Lua基础coroutine(协程)

1.创建协程 协程和多线程下的线程类似:有自己的堆栈,自己的局部变量,有自己的指令指针,但是和其他协程程序共享全局变量等信息。线程和协程的主要不同在于:多处理器的情况下,概念上来说多线程是同时运行多个线程,而协程是通过协作来完成,任何时刻只有一个协程程序在运行。并且这个在运行的协程只有明确被要求挂起时才会被挂起。 [plain] view plain copy --创建协程  

活在阳光下 780

Python基础之协程(Coroutine)

引言 之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。 随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一...

PythonGo 1万+

lua的coroutine 协同程序基础

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34365635的博客 145

Lua基础(十六)协程 Coroutine

高并发的核心

wzj_110的博客 1319
上一篇: 初遇Kotlin协程
下一篇: NIM简单实践-图像分割
xiongmaozhijin
博客等级 码龄15年 4粉丝 27原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值