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

在module_init函数中调用调度,它永远不会返回

是因为调度函数会将当前进程的执行权交给其他可执行的进程,而不会再返回到调用它的函数。

调度是操作系统中的一个重要功能,用于决定哪个进程可以占用CPU资源进行执行。在Linux内核中,调度函数负责根据一定的调度算法选择下一个要执行的进程,并将CPU的控制权交给该进程。

在module_init函数中调用调度的场景可能是为了让其他进程有机会执行,以提高系统的并发性能或者避免某个进程长时间占用CPU资源导致系统响应变慢。

然而,调度函数一旦被调用,当前进程就会被放入就绪队列中等待下一次调度,而不会再返回到调用它的函数。这意味着在module_init函数中调用调度后,该函数不会继续执行后续的代码,也不会返回任何结果。

需要注意的是,调度函数的具体实现和调度算法可能因操作系统的不同而有所差异。因此,在具体应用中,需要根据实际情况选择适合的调度策略和调度函数。

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

  • 腾讯云云服务器(CVM):提供弹性计算能力,满足各种业务需求。产品介绍链接
  • 腾讯云容器服务(TKE):基于Kubernetes的容器管理服务,简化容器化应用的部署和管理。产品介绍链接
  • 腾讯云函数计算(SCF):无服务器计算服务,帮助开发者更轻松地构建和运行事件驱动型应用。产品介绍链接
  • 腾讯云数据库(TencentDB):提供多种数据库产品,包括关系型数据库、NoSQL数据库等,满足不同业务场景的需求。产品介绍链接
  • 腾讯云CDN:内容分发网络服务,加速静态资源的传输,提升用户访问体验。产品介绍链接
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

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

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

8.3K30

linux内核线程「建议收藏」

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

1.5K30
  • 异步处理的强力助手:Linux Workqueue 机制详解

    workqueue机制允许中断处理程序将任务提交给工作队列,在稍后的时间异步执行。这样,中断处理程序可以立即返回,并且不会阻塞其他中断处理程序的执行。工作队列是一组线程,它们可以同时执行多个任务。...workqueue是Linux系统中用于实现异步任务调度的机制,它允许驱动程序和内核线程安排延迟执行的工作。...,并将其添加到调用进程中。...工作者线程则会不断从队列的头部取出工作对象,并调用与之关联的处理函数来执行工作。当工作者线程从工作队列中取出一个工作对象时,它会检查这个对象是否已经被取消或者延迟执行。...在每个工作结构体的数据字段中,使用指向任务编号的指针来标识每个任务。最后,在清理模块时,通过调用flush_workqueue函数来确保所有任务都已经被执行完毕,然后再删除工作队列。

    60810

    详解 | 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表明函数除 返回值外,不会通过其它(如全局变量、指针)对函数外部产生任何影响。

    2.1K20

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

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

    56920

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

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

    2.1K50

    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内核源代码中自己封装出来的一个打印函数,是内核源码中的一个普通函数

    2.1K20

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

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

    90941

    EnterCriticalSection TryEnterCriticalSection

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

    21710

    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

    1.1K50

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

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

    2.8K40

    Go Goroutine

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

    43120

    创建任务与任务管理

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

    1.1K20
    领券