iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >Linux中如何实现poll机制
  • 892
分享到

Linux中如何实现poll机制

2023-06-12 20:06:16 892人浏览 八月长安
摘要

这篇文章给大家分享的是有关linux中如何实现poll机制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数。比如系统调用open

这篇文章给大家分享的是有关linux中如何实现poll机制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数。比如系统调用open、read、write、poll,与之对应的内核函数为:sys_open、sys_read、sys_write、sys_poll。

一、内核框架:

对于系统调用poll或select,它们对应的内核函数都是sys_poll。分析sys_poll,即可理解poll机制。

sys_poll函数位于fs/select.c文件中,代码如下:

asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,long timeout_msecs){s64 timeout_jiffies;if (timeout_msecs > 0) {#if HZ > 1000if (timeout_msecs / 1000 > (s64)0x7fffffffffffffffULL / (s64)HZ)timeout_jiffies = -1;else#endiftimeout_jiffies = msecs_to_jiffies(timeout_msecs);} else {timeout_jiffies = timeout_msecs;}return do_sys_poll(ufds, nfds, &timeout_jiffies);}

它对超时参数稍作处理后,直接调用do_sys_poll。

do_sys_poll函数也位于位于fs/select.c文件中,我们忽略其他代码:

int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout){……poll_initwait(&table);……fdcount = do_poll(nfds, head, &table, timeout);……}

poll_initwait函数非常简单,它初始化一个poll_wqueues变量table:

poll_initwait > init_poll_funcptr(&pwq->pt, __pollwait); > pt->qproc = qproc;

即table->pt->qproc = __pollwait,__pollwait将在驱动的poll函数里用到。

do_sys_poll函数位于fs/select.c文件中,代码如下:

static int do_poll(unsigned int nfds,struct poll_list *list,struct poll_wqueues *wait, s64 *timeout){01 &hellip;&hellip;02for (;;) {03 &hellip;&hellip;04if (do_pollfd(pfd, pt)) {05count++;06pt = NULL;07}08 &hellip;&hellip;09if (count || !*timeout || signal_pending(current))10break;11count = wait->error;12if (count)13break;1415if (*timeout < 0) {1617__timeout = MAX_SCHEDULE_TIMEOUT;18} else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT-1)) {1923__timeout = MAX_SCHEDULE_TIMEOUT - 1;24*timeout -= __timeout;25} else {26__timeout = *timeout;27*timeout = 0;28}2930__timeout = schedule_timeout(__timeout);31if (*timeout >= 0)32*timeout += __timeout;33}34__set_current_state(TASK_RUNNING);35return count;36 }

分析其中的代码,可以发现,它的作用如下:

①从02行可以知道,这是个循环,它退出的条件为:

a. 09行的3个条件之一(count非0,超时、有信号等待处理)

count顺0表示04行的do_pollfd至少有一个成功。

b. 11、12行:发生错误

②重点在do_pollfd函数,后面再分析

③第30行,让本进程休眠一段时间,注意:应用程序执行poll调用后,如果①②的条件不满足,进程就会进入休眠。那么,谁唤醒呢?除了休眠到指定时间被系统唤醒外,还可以被驱动程序唤醒──记住这点,这就是为什么驱动的poll里要调用poll_wait的原因,后面分析。

do_pollfd函数位于fs/select.c文件中,代码如下:

static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait){&hellip;&hellip;if (file->f_op && file->f_op->poll)mask = file->f_op->poll(file, pwait);&hellip;&hellip;}

可见,它就是调用我们的驱动程序里注册的poll函数。

二、驱动程序:

驱动程序里与poll相关的地方有两处:一是构造file_operation结构时,要定义自己的poll函数。二是通过poll_wait来调用上面说到的__pollwait函数,pollwait的代码如下:

static inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p){if (p && wait_address)p->qproc(filp, wait_address, p);}

p->qproc就是__pollwait函数,从它的代码可知,它只是把当前进程挂入我们驱动程序里定义的一个队列里而已。它的代码如下:

static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,poll_table *p){struct poll_table_entry *entry = poll_get_entry(p);if (!entry)return;get_file(filp);entry->filp = filp;entry->wait_address = wait_address;init_waitqueue_entry(&entry->wait, current);add_wait_queue(wait_address, &entry->wait);}

执行到驱动程序的poll_wait函数时,进程并没有休眠,我们的驱动程序里实现的poll函数是不会引起休眠的。让进程进入休眠,是前面分析的do_sys_poll函数的30行“__timeout = schedule_timeout(__timeout)”。

poll_wait只是把本进程挂入某个队列,应用程序调用poll > sys_poll > do_sys_poll > poll_initwait,do_poll > do_pollfd > 我们自己写的poll函数后,再调用schedule_timeout进入休眠。如果我们的驱动程序发现情况就绪,可以把这个队列上挂着的进程唤醒。可见,poll_wait的作用,只是为了让驱动程序能找到要唤醒的进程。即使不用poll_wait,我们的程序也有机会被唤醒:chedule_timeout(__timeout),只是休眠__time_out这段时间。

现在来总结一下poll机制:

poll > sys_poll > do_sys_poll > poll_initwait,poll_initwait函数注册一下回调函数__pollwait,它就是我们的驱动程序执行poll_wait时,真正被调用的函数。

接下来执行file->f_op->poll,即我们驱动程序里自己实现的poll函数

它会调用poll_wait把自己挂入某个队列,这个队列也是我们的驱动自己定义的;

它还判断一下设备是否就绪。

如果设备未就绪,do_sys_poll里会让进程休眠一定时间

进程被唤醒的条件有2:一是上面说的“一定时间”到了,二是被驱动程序唤醒。驱动程序发现条件就绪时,就把“某个队列”上挂着的进程唤醒,这个队列,就是前面通过poll_wait把本进程挂过去的队列。

如果驱动程序没有去唤醒进程,那么chedule_timeout(__timeou)超时后,会重复2、3动作,直到应用程序的poll调用传入的时间到达。

感谢各位的阅读!关于“Linux中如何实现poll机制”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Linux中如何实现poll机制

本文链接: https://www.lsjlt.com/news/262757.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Linux中如何实现poll机制
    这篇文章给大家分享的是有关Linux中如何实现poll机制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。所有的系统调用,基于都可以在它的名字前加上“sys_”前缀,这就是它在内核中对应的函数。比如系统调用open...
    99+
    2023-06-12
  • checkpoint机制如何实现
    这篇文章主要讲解了“checkpoint机制如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“checkpoint机制如何实现”吧!checkpoint 机制的具体实现我们都知道为了优化...
    99+
    2023-07-05
  • linux中Bash如何实现作业控制
    这篇文章主要为大家展示了“linux中Bash如何实现作业控制”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux中Bash如何实现作业控制”这篇文章吧。作业控制Bash环境中通过命令开启进...
    99+
    2023-06-27
  • Linux如何实现远程控制
    小编给大家分享一下Linux如何实现远程控制,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Linux一般作为服务器使用,而服务器一般放在机房,你不可能在机房操作你...
    99+
    2023-06-28
  • Kafka中的消息复制机制是如何实现的
    Kafka中的消息复制机制是通过复制分区来实现的。在Kafka中,每个主题可以分为多个分区,每个分区可以有多个副本。当生产者发送消息...
    99+
    2024-04-02
  • python的import机制如何实现
    本篇内容主要讲解“python的import机制如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python的import机制如何实现”吧!import 机制功能Python 的 impo...
    99+
    2023-06-30
  • 如何实现C++中的异常处理机制?
    如何实现C++中的异常处理机制引言:异常处理是编程中非常重要的一部分,它可以提高程序的可靠性和稳定性。在C++中,异常处理机制可以帮助我们处理程序中的错误和异常情况,使得程序的控制流能够在异常发生时进行变更,从而避免程序的崩溃。本文将介绍C...
    99+
    2023-11-02
    异常处理机制 (Exception Handling) C++异常 (C++ Exceptions) 异常处理语句 (E
  • linux如何强制关机
    这篇文章将为大家详细讲解有关linux如何强制关机,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。概念和术语内核模块允许 Linux 内核在运行时动态地向其中插入和删除代码。这些模块是具有独立功能的程序,可...
    99+
    2023-06-15
  • Linux系统中workqueue机制如何理解
    本篇文章给大家分享的是有关Linux系统中workqueue机制如何理解,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。workqueue简介:Linux中的Workqueue机...
    99+
    2023-06-28
  • java的反射机制如何实现
    Java的反射机制是指在运行时动态获取和操作类的相关信息的能力。通过反射,可以在运行时获取类的属性、方法、构造函数等信息,还可以动态...
    99+
    2023-08-31
    java
  • Node如何实现JWT鉴权机制
    这篇文章主要介绍“Node如何实现JWT鉴权机制”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Node如何实现JWT鉴权机制”文章能帮助大家解决问题。一、为什么使用JWT一种技术的出现,就是弥补另一...
    99+
    2023-07-04
  • 如何在Python中实现高效的缓存机制?
    Python 是一门高效、易学的编程语言,但在处理大量数据时,常常会遇到性能瓶颈。为了提高程序的运行效率,我们可以采用缓存机制。 缓存机制是将某些计算结果保存在内存中,以便下次需要时能够快速获取。在 Python 中,我们可以利用内置的 f...
    99+
    2023-06-28
    load 缓存 开发技术
  • 如何在Samza中实现容错和恢复机制
    在Samza中实现容错和恢复机制通常涉及以下几个步骤: 使用状态存储:Samza提供了本地和远程状态存储机制,可以用来存储作业的...
    99+
    2024-04-02
  • linux下如何实现定时关机
    这篇文章主要讲解了“linux下如何实现定时关机”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“linux下如何实现定时关机”吧!用crontab命令就可以了,下面看一下它的详细用法。名称 :...
    99+
    2023-06-10
  • 如何实现Redis的LRU缓存机制
    这篇文章给大家分享的是有关如何实现Redis的LRU缓存机制的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用...
    99+
    2023-06-14
  • 如何理解Spring AOP的实现机制
    这篇文章将为大家详细讲解有关如何理解Spring AOP的实现机制,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。AOP(Aspect Orient Programming),一般称为面向切面...
    99+
    2023-06-16
  • ahooks控制时机的hook如何实现
    本篇内容主要讲解“ahooks控制时机的hook如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ahooks控制时机的hook如何实现”吧!Function Component VS Cl...
    99+
    2023-07-02
  • java反射机制是如何实现的
    Java反射机制是通过Java的`java.lang.reflect`包中的类和接口来实现的。该包中包含了一些重要的类,如`Clas...
    99+
    2023-10-08
    java
  • C语言如何实现位段机制
    这篇文章主要为大家展示了“C语言如何实现位段机制”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言如何实现位段机制”这篇文章吧。概念什么是位段?位段又称为位域,C语言允许在一个结构体中以位为单...
    99+
    2023-06-29
  • Java 中的存储机制:如何实现并发对象?
    Java 是一种广泛使用的编程语言,其具有高效性、可靠性和安全性。在 Java 中,对象是存储在堆上的。在多线程应用程序中,对象的并发性是非常重要的。在本文中,我们将介绍 Java 中的存储机制,以及如何实现并发对象。 Java 中的存储...
    99+
    2023-08-14
    存储 并发 对象
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作