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

【Kotlin 协程】Flow 异步流 ① ( 以异步返回返回多个返回值 | 同步调用返回多个值的弊端 | 尝试 sequence 调用挂起函数返回多个返回值 | 协程调用挂起函数返回集合 )

文章目录 一、以异步返回返回多个返回值 二、同步调用返回多个值的弊端 三、尝试 sequence 调用挂起函数返回多个返回值 四、协程调用挂起函数返回集合 一、以异步返回返回多个返回值 ----... Kotlin 协程 Coroutine , 使用 suspend 挂起函数 以异步的方式 返回单个返回值肯定可以实现 , 参考 【Kotlin 协程】协程的挂起和恢复 ① ( 协程的挂起和恢复概念...sequence 调用挂起函数返回多个返回值 ---- 尝试使用 挂起函数 kotlinx.coroutines.delay 进行休眠 , 这样挂起时 , 不影响主线程的其它操作 , 此时会报如下错误...SequenceScope 对象的方法 ; 该匿名函数 , 不能调用 SequenceScope 之外定义的挂起函数 , 这样做是为了保证该类的执行性能 ; /** * 构建一个[Sequence...---- 如果要 以异步方式 返回多个返回值 , 可以协程调用挂起函数返回集合 , 但是该方案只能一次性返回多个返回值 , 不能持续不断的 先后 返回 多个 返回值 ; 代码示例 : package

8.2K30

linux内核线程「建议收藏」

内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,mm指针被设置为NULL;只在内核空间运行,从来不切换到用户空间去;并且和普通进程一样,可以被调度,也可以被抢占。...调用do_fork去创建的。...新创建的线程开始运行后,入口kthread(),kthread()调用complete(&create->done)唤醒阻塞的模块进程,并使用schedule()调度出去。...但如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远返回并且不检查信号,它将永远不会停止,因此,线程函数必须能让出CPU,以便能运行其他线程。...同时线程函数也必须能重新被调度运行。例子程序,这是通过schedule_timeout()函数完成的(下面的例子会看到)。

1.3K30
您找到你想要的搜索结果了吗?
是的
没有找到

详解 | Linux驱动入口函数module_init如何被调用

几乎每个Linux驱动都有个module_init(与module_exit的定义Init.h (/include/linux) )。没错,驱动的加载就靠。为什么需要这样一个宏?...原因是按照一般的编程想法,各部分的初始化函数会在一个固定的函数调用比如: void init(void) { init_a(); init_b(); } 如果再加入一个初始化函数呢,...告诉连接器这个变量存放在.initlist区段,如果所有的初始化函数都是用这个宏,那么每个函数会有对应的一个initlist_t结构体变量存放在.initlist区段,也就是说我们可以.initlist...与此类似,内核也是用到这种方法,所以我们写驱动的时候比较独立,不用我们自己添加代码一个固定的地方来调用我们自己的初始化函数和退出函数,连接器已经为我们做好了。先来分析一下module_init。...比如对函数,noline将禁止进行内联扩展、noreturn表示没有返回值、pure表明函数返回值外,不会通过其它(如全局变量、指针)对函数外部产生任何影响。

1.8K20

生生世世 —— schedule 的轮回(七)

从前面的代码分析可以得知,上面调度循环中的每一个函数调用都没有返回,虽然 goroutine任务->goexit()->goexit1()->mcall() 是 g2 的栈空间执行的,但剩下的函数都是...那么问题就来了,一个复杂的程序调度可能会进行无数次循环,也就是说会进行无数次没有返回函数调用,大家都知道,每调用一次函数都会消耗一定的栈空间,而如果一直这样无返回调用下去无论 g0 有多少栈空间终究是会耗尽的...关键点就在于,每次执行 mcall 切换到 g0 栈时都是切换到 g0.sched.sp 所指的固定位置,这之所以行得通,正是因为从 schedule 函数开始之后的一系列函数永远不会返回,所以重用这些函数上一轮调度时所使用过的栈内存是没有问题的...我再解释一下:栈空间调用函数时会自动“增大”,而函数返回时,会自动“减小”,这里的增大和减小是指栈顶指针 SP 的变化。...上述这些函数都没有返回,说明调用者不需要用到被调用者的返回值,有点像“尾递归”。 因为 g0 一直没有动过,所有之前保存的 sp 还能继续使用。每一次调度循环都会覆盖上一次调度循环的栈数据,完美!

55520

Linux驱动开发-内核共享工作队列

内核工作队列 工作队列常见的使用形式是配合中断使用,中断的服务函数里无法调用会导致休眠的相关函数代码,有了工作队列机制以后,可以将需要执行的逻辑代码放在工作队列里执行,只需要在中断服务函数里触发即可,...工作队列里,我们把推后执行的任务叫做工作(work),描述的数据结构为work_struct,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue_struct,而工作线程就是负责执行工作队列的工作...内核使用这个结构来描述一个工作,一个工作简单理解就是对应于一个函数,可以通过内核调度函数调用work_structfunc指针所指向的函数。...(&work, work_func); 3)适当的地方调度工作 如果工作用于中断底部代码,则在中断顶部调度。...案例代码 3.1 共享工作队列-按键驱动 下面这份代码是一个按键驱动代码,在按键中断服务函数调度共享队列,最终工作函数里完成按键值的检测打印。工作队列采用的是共享工作队列。

2K50

09.字符设备驱动

被驱动入口函数调用。first_drv_init()   4.如何知道调用first_drv_init(),还是其他的函数呢?...如何知道何时来调用first_drv_exit?module_init(first_drv_exit)定义一个结构体,结构体中有函数指针,指向入口函数。...倘若没有按键按下,那么超过多少时间之后,也要返回超时错误信息,进程能够继续得到执行,而不是没有按键按下,就永远休眠。...原子操作   原子操作指的是执行过程不会被别的代码路径所中断的操作。   ...被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。 非阻塞操作   进程不能进行设备操作时并不挂起,或者放弃,或者不停地查询,直至可以进行操作为止。

2.2K20

Linux笔记(13)| 字符设备驱动基础入门

这些层次关系大致就是:用户提出要求,应用开发者通过调用系统的API接口来实现功能,API接口是操作系统提供的,的底层就是驱动程序,而驱动程序再往下就是操作系统内核,内核再往下就是硬件了。...) { int ret = -1; printk(KERN_INFO "chrdev_init helloworld init\n"); // module_init调用函数中去注册字符设备驱动...helloworld exit\n"); // module_exit宏调用函数中去注销字符设备驱动 unregister_chrdev(MYMAJOR, MYNAME); } module_init...讲register_chrdev这个函数之前,要先讲一下file_operations这个结构体。这是一个非常重要的结构体,的作用就是将系统的API接口和你自己写的驱动的接口“连接”起来。...(2)printk和printf最大的差别:printf是C库函数,是应用层编程中使用的,不能在linux内核源代码中使用;printk是linux内核源代码自己封装出来的一个打印函数,是内核源码的一个普通函数

2K20

Linux设备驱动程序(二)——建立和运行模块

内核需要它自己的打印函数,因为靠自己运行,没有 C 库的帮助,模块能够调用 printk 是因为 insmod 加载了之后,模块被连接到内核并且可存取内核的公用符号。...code here */ } module_init(initialization_function); 初始化函数应当声明成静态的,因为它们不会在特定文件之外可见; 声明的 __init 标志可能看起来有点怪...没有这个定义,你的初始化函数不会调用; 大部分注册函数以 register_ 做前缀,因此找到它们的另外一个方法是在内核源码里查找 register_; 1、清理函数 每个非试验性的模块也要求有一个清理函数...,注销接口,模块被去除之前返回所有资源给系统。...用户内存是可交换的,不象内核内存,一个不常使用的却有很大一个驱动的设备不会占据别的程序可以用到的 RAM,除了实际在用时。

66741

EnterCriticalSection TryEnterCriticalSection

如果EnterCriticalSection将一个线程置于等待状态,那么该线程很长时间内就不能再次被调度。实际上,在编写得不好的应用程序,该线程永远不会再次被赋予CPU时间。...TryEnterCriticalSection函数决不允许调用线程进入等待状态。返回值能够指明调用线程是否能够获得对资源的访问权。...TryEnterCriticalSection发现该资源已经被另一个线程访问,它就返回FALSE。在其他所有情况下,返回TRUE。...运用这个函数,线程能够迅速查看它是否可以访问某个共享资源,如果不能访问,那么它可以继续执行某些其他操作,而不必进行等待。...如果TryEnterCriticalSection函数确实返回了TRUE,那么CRITICAL_SECTION的成员变量已经更新。

20010

使用kotlin协程提高app性能(译)

要在主线程之外运行代码,您可以告诉Kotlin协程Default或IO调度程序上执行工作。Kotlin,所有协同程序必须在调度程序运行,即使它们主线程上运行。...继续前面的示例,您可以使用调度程序重新定义get函数get的主体内部,调用withContext(Dispatchers.IO)来创建一个IO线程池上运行的块。...一个好的做法是使用withContext()来确保每个函数都是主安全的,这意味着您可以从主线程调用函数。 这样,调用永远不需要考虑应该使用哪个线程来执行该函数。...由于async期望某个时刻最终调用await,它会保留异常并在await调用重新抛出它们。 这意味着如果您使用await从常规函数启动新的协同程序,则可能会以静默方式删除异常。...这些丢弃的异常不会出现在崩溃指标,也不会出现在logcat。 并行分解 当函数返回时,必须停止由挂起函数启动的所有协同程序,因此您可能需要保证这些协程返回之前完成。

2.3K10

2.制作第一个驱动程序

入口函数调用这个register_chrdev()注册函数, (5)通过module_init()来修饰入口函数,使内核知道有这个函数 (6)写驱动的first_drv_exit出口函数调用这个unregister_chrdev...0; } /*5 module_init修饰入口函数*/ module_init(first_drv_init); /*6 写first_drv_exit出口函数*/ void first_drv_exit...结果如上图,发现测试程序里的open()函数调用了驱动的first_drv_open() write()函数调用了驱动的first_drv_write(), 其中open()函数返回值为3,是因为描述符...制作根文件系统之使用里有介绍 7.3 接下来使用insmod自动创建设备节点, rmmod自动注销设备节点 (1)首先创建一个class设备类,class是一个设备的高级视图,抽象出低级的实现细节,...//创建一个class类 static struct class_device *firstdrv_class_devs; //创建类的设备 (2)first_drv_init入口函数添加: firstdrv_class

1K50

Go Goroutine

操作系统创建一个进程要为分配独立的存储空间和CPU。进程对CPU的占用并不是持续的,而是分时间片使用。线程是隶属于某个进程的子任务,是操作系统最小的调度单位 。...同时我们的代码也会继续往后执行不会等待Goroutine返回。所以上面的例子执go helloWorld()之后不等打印Hello World就继续往下执行了。...这是因为go关键后面的匿名函数Goroutine执行,不会阻塞for循环执行。那如果想输出0-9全部数字该怎么办呢?...如果我们创建了一个Goroutine,但是意外导致这个Goroutine永远不会退出,那么为此Goroutine分配的内存就永远不会释放,我们称这种情况为Goroutine泄漏。...要防止Goroutine泄漏我们创建一个Goroutine时必须要考虑何时退出。

41520

创建任务与任务管理

如果还是使用裸机编程的那种延时,那么整个任务就成为了一个死循环,如果恰好该任务的优先级是最高的,那么系统永远都是在这个任务运行,比它优先级更低的任务无法运行,根本无法实现多任务,因此任务必须有能阻塞任务的函数...其实最主要的无非就是调用OSTaskCreate()这个函数,前面的那些定义也是根据这个函数的输入参数来的,当你看到的输入参数的时候,你自然就会知道要去定义前面那些东西了。然后就编写任务函数。...如果创建多个任务,那么,我们是main函数里先创建一个起始任务,然后的起始任务函数里再创建其他的任务,同时删除或者挂起这个起始任务。当然,我们得为每一个任务定义好任务堆栈,任务控制块这些。...,里面的资源都被系统释放掉,但是挂起任务就不会这样子,调用挂起任务函数,仅仅是将任务进入挂起态,其内部的资源都会保留下来,同时也不会参与系统任务的调度,当调用恢复函数的时候,整个任务立即从挂起态进入就绪态...另外还需注意一下中断服务函数是一种需要特别注意的上下文环境,运行在非任务的执行环境下(一般为芯片的一种特殊运行模式(也被称作特权模式)),在这个上下文环境不能使用挂起当前任务的操作,不允许调用任何会阻塞运行的

1K20

Linux内核跟踪:ftrace hook入门手册(上)

这个空白区可以需要的时候被替换为对ftrace相关函数调用,从而实现对特定内核函数调用追踪,而不会过度影响其它内核函数的运行性能。 关于ftrace的详细内部机制,受限于篇幅,本文不详细介绍。...随后,我们可以列出内核模块: lsmod 如果此前已经安装成功,应该可以列表中看到: 图7:列出内核模块 类似地,我们也可以卸载已安装的内核模块: rmmod HelloWorld 这个命令正常运行时也不会产生任何输出...context.Hook->Handler(&context)) //返回false则阻止原始函数执行(直接返回到原始函数调用方),其余情况不需要特殊操作,任由ftrace框架恢复执行流程即可...修改ip的跳转方法导致经典方案对hook子程的执行发生在ftrace相关函数返回之后(而非ftrace相关函数栈内),因此ftrace自带的防递归功能无法作用于经典方案。...B的函数,而模块B尝试调用被hook的原始函数)可能是不完善的; 第二种方法执行递归调用时跳过系统调用开头的“空白区”,这意味着需要对于所有调用原始函数的代码进行修改。

2.4K40

深入理解并发并行,阻塞非阻塞,同步异步

阻塞调用是指调用结果返回之前,调用者会进入阻塞状态等待。只有得到结果之后才会返回。 非阻塞调用是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。...阻塞调用:比如 socket 的 recv(),调用这个函数的线程如果没有数据返回,它会一直阻塞着,也就是 recv() 后面的代码都不会执行了,程序就停在 recv() 这里等待,所以一般把 recv...非阻塞调用:比如非阻塞socket 的 send(),调用这个函数只是把待发送的数据复制到TCP输出缓冲区,就立刻返回了,线程并不会阻塞,数据有没有发出去 send() 是不知道的,不会等待发出去才返回的...同步,异步 同步:发出一个同步调用时,没有得到结果之前,该调用就不返回。 异步:发出一个异步调用后,调用不会立刻得到结果,该调用返回了。...CPU调度策略 并发运行,CPU需要在多个程序之间来回切换,那么如何切换就有一些策略 3.1 先来先服务 - 时间片轮转调度 这个很简单,就是谁先来,就给谁分配时间片运行,缺点是有些紧急的任务要很久才能得到运行

1.2K10
领券