【转】Linux-2.6.25 select系统调用源码分析

源码解读poll/select内核机制 在前面的文章select/poll/epoll对比分析,从使用者的角度讲述了三者之间的关系。select/poll/epoll都是IO多路监控机制,通过监控文件描述符读写状态来通知相应程序执行操作的一个机制。再往深处问一个他们底层又是如何实现,可以做得监控文件状态的功能呢?本文先回顾select/poll机制的使用与源码,下一篇文章再来单独能实现高并发的epoll机制。等待队列:当事件满足要求,则唤醒所有的等待队列项。一个进程可以等待多个不同等待队列,以及指定相应的唤醒时回调函数。 阅读详情

转自:http://zhangyafeikimi.iteye.com/blog/248815

Linux 2.6.25中的select系统调用 

主要有4个函数: 
sys_select:处理时间参数,调用core_sys_select。 
core_sys_select:处理三个fd_set参数,调用do_select。 
do_select:做select/poll的工作。在合适的时机把自己挂起等待,调用sock_poll。 
sock_poll:用函数指针分派到具体的协议层函数tcp_poll、udp_poll、datagram_poll。 
层层分工明确,我也要多学习这种方式啊。 
C代码  
  1. /* 
  2. sys_select(fs/select.c) 
  3. 处理了超时值(如果有),将struct timeval转换成了时钟周期数,调用core_sys_select,然后检查剩余时间,处理时间 
  4. */  
  5. asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,  
  6.                            fd_set __user *exp, struct timeval __user *tvp)  
  7. {  
  8.     s64 timeout = -1;  
  9.     struct timeval tv;  
  10.     int ret;  
  11.   
  12.     if (tvp) {/*如果有超时值*/  
  13.         if (copy_from_user(&tv, tvp, sizeof(tv)))  
  14.             return -EFAULT;  
  15.   
  16.         if (tv.tv_sec < 0 || tv.tv_usec < 0)/*时间无效*/  
  17.             return -EINVAL;  
  18.   
  19.         /* Cast to u64 to make GCC stop complaining */  
  20.         if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)  
  21.             timeout = -1;   /* 无限等待*/  
  22.         else {  
  23.             timeout = DIV_ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ);  
  24.             timeout += tv.tv_sec * HZ;/*计算出超时的相对时间,单位为时钟周期数*/  
  25.         }  
  26.     }  
  27.   
  28.     /*主要工作都在core_sys_select中做了*/  
  29.     ret = core_sys_select(n, inp, outp, exp, &timeout);  
  30.   
  31.     if (tvp) {/*如果有超时值*/  
  32.         struct timeval rtv;  
  33.   
  34.         if (current->personality & STICKY_TIMEOUTS)/*模拟bug的一个机制,不详细描述*/  
  35.             goto sticky;  
  36.         /*rtv中是剩余的时间*/  
  37.         rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));  
  38.         rtv.tv_sec = timeout;  
  39.         if (timeval_compare(&rtv, &tv) >= 0)/*如果core_sys_select超时返回,更新时间*/  
  40.             rtv = tv;  
  41.         /*拷贝更新后的时间到用户空间*/  
  42.         if (copy_to_user(tvp, &rtv, sizeof(rtv))) {  
  43. sticky:  
  44.             /* 
  45.             * If an application puts its timeval in read-only 
  46.             * memory, we don't want the Linux-specific update to 
  47.             * the timeval to cause a fault after the select has 
  48.             * completed successfully. However, because we're not 
  49.             * updating the timeval, we can't restart the system 
  50.             * call. 
  51.             */  
  52.             if (ret == -ERESTARTNOHAND)/*ERESTARTNOHAND表明,被中断的系统调用*/  
  53.                 ret = -EINTR;  
  54.         }  
  55.     }  
  56.   
  57.     return ret;  
  58. }  
  59.   
  60.   
  61.   
  62.   
  63.   
  64.   
  65. /*core_sys_select 
  66. 为do_select准备好了位图,然后调用do_select,将返回的结果集,返回到用户空间 
  67. */  
  68. static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,  
  69.                            fd_set __user *exp, s64 *timeout)  
  70. {  
  71.     fd_set_bits fds;  
  72.     void *bits;  
  73.     int ret, max_fds;  
  74.     unsigned int size;  
  75.     struct fdtable *fdt;  
  76.     /* Allocate small arguments on the stack to save memory and be faster */  
  77.   
  78.     /*SELECT_STACK_ALLOC 定义为256*/  
  79.     long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];  
  80.   
  81.     ret = -EINVAL;  
  82.     if (n < 0)  
  83.         goto out_nofds;  
  84.   
  85.     /* max_fds can increase, so grab it once to avoid race */  
  86.     rcu_read_lock();  
  87.     fdt = files_fdtable(current->files);/*获取当前进程的文件描述符表*/  
  88.     max_fds = fdt->max_fds;  
  89.     rcu_read_unlock();  
  90.     if (n > max_fds)/*修正用户传入的第一个参数:fd_set中文件描述符的最大值*/  
  91.         n = max_fds;  
  92.   
  93.     /* 
  94.     * We need 6 bitmaps (in/out/ex for both incoming and outgoing), 
  95.     * since we used fdset we need to allocate memory in units of 
  96.     * long-words.  
  97.     */  
  98.   
  99.     /* 
  100.     如果stack_fds数组的大小不能容纳下所有的fd_set,就用kmalloc重新分配一个大数组。 
  101.     然后将位图平均分成份,并初始化fds结构 
  102.     */  
  103.     size = FDS_BYTES(n);  
  104.     bits = stack_fds;  
  105.     if (size > sizeof(stack_fds) / 6) {  
  106.         /* Not enough space in on-stack array; must use kmalloc */  
  107.         ret = -ENOMEM;  
  108.         bits = kmalloc(6 * size, GFP_KERNEL);  
  109.         if (!bits)  
  110.             goto out_nofds;  
  111.     }  
  112.     fds.in      = bits;  
  113.     fds.out     = bits +   size;  
  114.     fds.ex      = bits + 2*size;  
  115.     fds.res_in  = bits + 3*size;  
  116.     fds.res_out = bits + 4*size;  
  117.     fds.res_ex  = bits + 5*size;  
  118.   
  119.     /*get_fd_set仅仅调用copy_from_user从用户空间拷贝了fd_set*/  
  120.     if ((ret = get_fd_set(n, inp, fds.in)) ||  
  121.         (ret = get_fd_set(n, outp, fds.out)) ||  
  122.         (ret = get_fd_set(n, exp, fds.ex)))  
  123.         goto out;  
  124.   
  125.     zero_fd_set(n, fds.res_in);  
  126.     zero_fd_set(n, fds.res_out);  
  127.     zero_fd_set(n, fds.res_ex);  
  128.   
  129.   
  130.     /* 
  131.     接力棒传给了do_select 
  132.     */  
  133.     ret = do_select(n, &fds, timeout);  
  134.   
  135.     if (ret < 0)  
  136.         goto out;  
  137.   
  138.     /*do_select返回,是一种异常状态*/  
  139.     if (!ret) {  
  140.         /*记得上面的sys_select不?将ERESTARTNOHAND转换成了EINTR并返回。EINTR表明系统调用被中断*/  
  141.         ret = -ERESTARTNOHAND;  
  142.         if (signal_pending(current))/*当当前进程有信号要处理时,signal_pending返回真,这符合了EINTR的语义*/  
  143.             goto out;  
  144.         ret = 0;  
  145.     }  
  146.   
  147.     /*把结果集,拷贝回用户空间*/  
  148.     if (set_fd_set(n, inp, fds.res_in) ||  
  149.         set_fd_set(n, outp, fds.res_out) ||  
  150.         set_fd_set(n, exp, fds.res_ex))  
  151.         ret = -EFAULT;  
  152.   
  153. out:  
  154.     if (bits != stack_fds)  
  155.         kfree(bits);/*对应上面的kmalloc*/  
  156. out_nofds:  
  157.     return ret;  
  158. }  
  159.   
  160.   
  161.   
  162.   
  163.   
  164.   
  165.   
  166.   
  167. /*do_select 
  168. 真正的select在此,遍历了所有的fd,调用对应的xxx_poll函数 
  169. */  
  170. int do_select(int n, fd_set_bits *fds, s64 *timeout)  
  171. {  
  172.     struct poll_wqueues table;  
  173.     poll_table *wait;  
  174.     int retval, i;  
  175.   
  176.     rcu_read_lock();  
  177.     /*根据已经打开fd的位图检查用户打开的fd, 要求对应fd必须打开, 并且返回最大的fd*/  
  178.     retval = max_select_fd(n, fds);  
  179.     rcu_read_unlock();  
  180.   
  181.     if (retval < 0)  
  182.         return retval;  
  183.     n = retval;  
  184.   
  185.   
  186.     /*将当前进程放入自已的等待队列table, 并将该等待队列加入到该测试表wait*/  
  187.     poll_initwait(&table);  
  188.     wait = &table.pt;  
  189.   
  190.     if (!*timeout)  
  191.         wait = NULL;  
  192.     retval = 0;  
  193.   
  194.     for (;;) {/*死循环*/  
  195.         unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;  
  196.         long __timeout;  
  197.   
  198.         /*注意:可中断的睡眠状态*/  
  199.         set_current_state(TASK_INTERRUPTIBLE);  
  200.   
  201.         inp = fds->in; outp = fds->out; exp = fds->ex;  
  202.         rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex;  
  203.   
  204.   
  205.         for (i = 0; i < n; ++rinp, ++routp, ++rexp) {/*遍历所有fd*/  
  206.             unsigned long in, out, ex, all_bits, bit = 1, mask, j;  
  207.             unsigned long res_in = 0, res_out = 0, res_ex = 0;  
  208.             const struct file_operations *f_op = NULL;  
  209.             struct file *file = NULL;  
  210.   
  211.             in = *inp++; out = *outp++; ex = *exp++;  
  212.             all_bits = in | out | ex;  
  213.             if (all_bits == 0) {  
  214.                 /* 
  215.                 __NFDBITS定义为(8 * sizeof(unsigned long)),即long的位数。 
  216.                 因为一个long代表了__NFDBITS位,所以跳到下一个位图i要增加__NFDBITS 
  217.                 */  
  218.                 i += __NFDBITS;  
  219.                 continue;  
  220.             }  
  221.   
  222.             for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1) {  
  223.                 int fput_needed;  
  224.                 if (i >= n)  
  225.                     break;  
  226.   
  227.                 /*测试每一位*/  
  228.                 if (!(bit & all_bits))  
  229.                     continue;  
  230.   
  231.                 /*得到file结构指针,并增加引用计数字段f_count*/  
  232.                 file = fget_light(i, &fput_needed);  
  233.                 if (file) {  
  234.                     f_op = file->f_op;  
  235.                     mask = DEFAULT_POLLMASK;  
  236.   
  237.                     /*对于socket描述符,f_op->poll对应的函数是sock_poll 
  238.                     注意第三个参数是等待队列,在poll成功后会将本进程唤醒执行*/  
  239.                     if (f_op && f_op->poll)  
  240.                         mask = (*f_op->poll)(file, retval ? NULL : wait);  
  241.   
  242.                     /*释放file结构指针,实际就是减小他的一个引用计数字段f_count*/  
  243.                     fput_light(file, fput_needed);  
  244.   
  245.                     /*根据poll的结果设置状态,要返回select出来的fd数目,所以retval++。 
  246.                     注意:retval是in out ex三个集合的总和*/  
  247.                     if ((mask & POLLIN_SET) && (in & bit)) {  
  248.                         res_in |= bit;  
  249.                         retval++;  
  250.                     }  
  251.                     if ((mask & POLLOUT_SET) && (out & bit)) {  
  252.                         res_out |= bit;  
  253.                         retval++;  
  254.                     }  
  255.                     if ((mask & POLLEX_SET) && (ex & bit)) {  
  256.                         res_ex |= bit;  
  257.                         retval++;  
  258.                     }  
  259.                 }  
  260.   
  261.                 /* 
  262.                 注意前面的set_current_state(TASK_INTERRUPTIBLE); 
  263.                 因为已经进入TASK_INTERRUPTIBLE状态,所以cond_resched回调度其他进程来运行, 
  264.                 这里的目的纯粹是为了增加一个抢占点。被抢占后,由等待队列机制唤醒。 
  265.  
  266.                 在支持抢占式调度的内核中(定义了CONFIG_PREEMPT),cond_resched是空操作 
  267.                 */   
  268.                 cond_resched();  
  269.             }  
  270.             /*根据poll的结果写回到输出位图里*/  
  271.             if (res_in)  
  272.                 *rinp = res_in;  
  273.             if (res_out)  
  274.                 *routp = res_out;  
  275.             if (res_ex)  
  276.                 *rexp = res_ex;  
  277.         }  
  278.         wait = NULL;  
  279.         if (retval || !*timeout || signal_pending(current))/*signal_pending前面说过了*/  
  280.             break;  
  281.         if(table.error) {  
  282.             retval = table.error;  
  283.             break;  
  284.         }  
  285.   
  286.         if (*timeout < 0) {  
  287.             /*无限等待*/  
  288.             __timeout = MAX_SCHEDULE_TIMEOUT;  
  289.         } else if (unlikely(*timeout >= (s64)MAX_SCHEDULE_TIMEOUT - 1)) {  
  290.             /* 时间超过MAX_SCHEDULE_TIMEOUT,即schedule_timeout允许的最大值,用一个循环来不断减少超时值*/  
  291.             __timeout = MAX_SCHEDULE_TIMEOUT - 1;  
  292.             *timeout -= __timeout;  
  293.         } else {  
  294.             /*等待一段时间*/  
  295.             __timeout = *timeout;  
  296.             *timeout = 0;  
  297.         }  
  298.   
  299.         /*TASK_INTERRUPTIBLE状态下,调用schedule_timeout的进程会在收到信号后重新得到调度的机会, 
  300.         即schedule_timeout返回,并返回剩余的时钟周期数 
  301.         */  
  302.         __timeout = schedule_timeout(__timeout);  
  303.         if (*timeout >= 0)  
  304.             *timeout += __timeout;  
  305.     }  
  306.   
  307.     /*设置为运行状态*/  
  308.     __set_current_state(TASK_RUNNING);  
  309.     /*清理等待队列*/  
  310.     poll_freewait(&table);  
  311.   
  312.     return retval;  
  313. }  
  314.   
  315.   
  316. static unsigned int sock_poll(struct file *file, poll_table *wait)  
  317. {  
  318.     struct socket *sock;  
  319.   
  320.     /*约定socket的file->private_data字段放着对应的socket结构指针*/  
  321.     sock = file->private_data;  
  322.   
  323.     /*对应了三个协议的函数tcp_poll,udp_poll,datagram_poll,其中udp_poll几乎直接调用了datagram_poll 
  324.     累了,先休息一下,这三个函数以后分析*/  
  325.     return sock->ops->poll(file, sock, wait);  
  326. }  




其他重要函数一览 
static int max_select_fd(unsigned long n, fd_set_bits *fds) 
返回在fd_set中已经打开的,并且小于用户指定最大值,的fd 

static inline int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 
从用户空间拷贝fd_set到内核 

static inline void zero_fd_set(unsigned long nr, unsigned long *fdset) 
把fd_set清零 

static inline unsigned long __must_check set_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset) 
把fd_set拷贝回用户空间 


static inline int signal_pending(struct task_struct *p) 
目前进程有信号需要处理 

struct file *fget_light(unsigned int fd, int *fput_needed) 
由fd得到其对应的file结构指针,并增加其引用计数 

static inline void fput_light(struct file *file, int fput_needed) 
释放由fget_light得到的file结构指针,减少其引用计数 

set_current_state 
设置当前进程的状态 

static inline int cond_resched(void) 
判断是否有进程需要抢占当前进程,如果是将立即发生调度。就是额外增加一个抢占点。 

signed long __sched schedule_timeout(signed long timeout) 
当前进程睡眠timeout个jiffies 

rcu_read_lock 
rcu_read_unlock 
Linux 2.6新加入的rcu锁。读锁的加锁、解锁函数 
参考http://www.ibm.com/developerworks/cn/linux/l-rcu 


poll_freewait 
poll_initwait 
poll_wait 
... 
和文件IO,poll机制有关的几个函数,参考《Linux设备驱动(第三版)》6.3 

tcp_poll 
udp_poll 
datagram_poll 
协议层的poll函数
select系统调用源码分析 select系统调用主要对select调用过程进行一些总结,后边也会跟着poll和epoll的一系列分析。对于分析select的源码版本是2.6.11.12。select系统调用的用途是:在一段指定时间内,监听用户感兴趣的文件描述符上的可读、可写和异常等事件。1. select系统调用的原型如下:#include &lt;sys/select.h&gt; int select( int nfds,... 阅读详情

相关推荐

Linux select内核源码剖析

poll Linux内核源码剖析 select Linux内核源码剖析 select Linux内核源码剖析 select的原理其实是和poll是一样的,都是采用轮询的方式。select相对于poll也许是比较节省空间吧,因为select是采用bitmap来标志的 本文先讲解一下如何在应用层使用select,然后再深入内核剖析select机制 select应用程序 select可以监听多个文件描述...

JT同学的博客 4378

网络篇之select

接收select内核的处理逻辑

weixin_46381158的博客 519

cobra-tools:一个简单的GUI,用于提取OVL和OVS存档并修改其内容

眼镜蛇工具 ” 生活改装找到了办法。” 一个简单的GUI,用于提取OVL和OVS存档并修改其内容,以及相关内部文件格式的编辑器。 还包括用于Blender的模型插件。 安装 在获取最新的源代码并将其解压缩到您选择的文件夹中。 您需要安装: (请确保在安装过程中将其添加到系统路径; 32位版本的python在尝试读取大型OVL时将达到其内存限制) (纹理转换所需-您可能已经安装了此功能) (需要lua反编译-现在为x86版本) pyqt5(运行:在cmd中pip install pyqt5 ) imageio(运行:在cmd中pip install imageio ) Blender插件安装 如何使用 基础教程 免责声明 切记备份所有mod文件和库存文件。 任何补丁都将重置或破坏mod,并且需要重做并重新发布。 目前尚不支持所有模型文件。 有些可能在导入或导出时崩溃。 即使

select系统调用

Linux 2.6.25中的select系统调用主要有4个函数: sys_select:处理时间参数,调用core_sys_select。 core_sys_select:处理三个fd_set参数,调用do_select。 do_select:做select/poll的工作

process的专栏 3043

Computer Networks 和 Computer & Security投稿经验

论文投稿

qq_50604294的博客 9234

RK3588平台-ES8388音频驱动调试与设备树配置实战

本文详细解析了在RK3588平台上调试ES8388音频驱动的实战过程。内容涵盖Linux音频驱动的三层架构(Machine、Platform、Codec),并重点提供了设备树(DTS)的完整配置示例,包括I2C节点、声卡节点及音频路由设置。文章还分享了驱动加载验证、amixer调试命令以及常见问题(如无声、变调)的排查思路,旨在帮助开发者快速完成RK3588与ES8388的音频系统集成。

mango的博客 807

1.IO multiplexing、select 、core_sys_select

1. 什么是IO multiplexing? IO multiplexing是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。在Linux系统中,常用的IO multiplexing手段有 select、poll 和 epoll。 IO multiplexing 主要用于处理网络请求,例如可以把多个请求句柄添加到 select 中进行监听,当有请求可进行IO的时候就会告知进程,并且把就绪的请求句柄保存下来,进程只需要对这些就绪的请求进行IO操作即可。下面通过一幅图来展示 select

cswhl的博客 405

c#窗体应用(.NET Framework)项目对Yaml文件进行写入与读取,Yaml数据转换成json

用到的技术与版本准备工作Yaml数据在C#中进行定义对Yaml文件的读取与写入代码的添加窗体控件控制操作写入数据到Yaml文件读取Yaml文件数据Yaml数据转换成json改进——对yaml文件读取时根据yaml文件中的键进行获取,对c#中怎么取名字无关yaml文件中多个数据读取遇到的问题总结的小点参考的文章在对Yaml文件进行读取前,先将Yaml文件中的数据结构在c#中进行定义,以便后面更好的读取。这里对这四个类型进行举例(这里为了想看看这四个类型到Yaml文件的格式是什么样子的)

永远年轻 1587

select 源码解析

函数原型:int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const timeval* timeout)select()的调用path如下:sys_select -> core_sys_select -> do_select1、sys_select()select属于系统调用,它进入内核态之后就调用

傲然君 1868

Vitis Model Composer闪退?手把手教你用命令行启动Vivado 2021后的System Generator

本文详细解析了Vitis Model Composer闪退问题的根本原因,并提供了命令行启动Vivado 2021后System Generator的完整解决方案。从环境变量配置、组件缺失排查到权限问题处理,手把手教你通过命令行深度排错,并分享高级自动化脚本和系统优化技巧,帮助开发者高效使用Vitis Model Composer与System Generator进行HDL开发。

weixin_26905487的博客 349

qq对接openclaw,通过qq发送命令

把 OpenClaw 接入 QQ 和微信,目前主流的微信文章和教程主要提供了两种截然不同的路径。我为你梳理了它们的核心区别和关键步骤,你可以根据自己的需求来选择。

suny8的专栏 270

Linux-2.6.25 select系统调用源码分析

来源:www.ibm.com/developerworks 本文以完整的源码的方式介绍如何在Linux 2.6.25中实现select系统调用。 Linux 2.6.25中的select系统调用 主要有4个函数: sys_select:处理时间参数,调用core_sys_select。 core_sys_select:处理三个fd_set参数,调用do_select。 do_selec

fengfengdiandia的专栏 2436

Ubuntu开机进入initramfs,解决办法来了!

摘要:Ubuntu系统启动时卡在initramfs界面,表明系统无法正常挂载根文件系统。常见原因包括引导配置错误、文件系统损坏、驱动程序问题和硬件故障。解决方法包括:1)使用fsck修复文件系统;2)通过dmesg排查驱动问题;3)检查硬盘等硬件状态;4)重新安装GRUB引导程序。建议做好系统备份等预防措施,遇到问题时按步骤排查。该问题通常可通过文件系统修复或引导配置重建解决。(148字)

米可的博客! 3421

Linux系统调用:select()系统调用源码分析

Linux select()系统调用源码分析 rtoax 2021年4月26日 先给出几个用户态select系统调用的socket示例程序:https://github.com/Rtoax/test/tree/master/ipc/socket/select 内核版本:linux-5.10.13 代码示例:select+eventfd 注释版代码:https://github.com/Rtoax/linux-5.10.13 1. select()系统调用 不做过多的解释,本文不对系统调用从用户态

RToax 984

【WRF数据准备】基于Python更新geo_em.d0.nc文件中Albedo/LAI等静态地理数据

基于Python更新geo_em.d0.nc文件中Albedo/LAI等静态地理数据

WW、forever的博客 591

[Dify实战] OA 公文排版助手:自动格式化、编号、生成摘要-带配套资源

摘要: Dify 公文排版助手通过自动化解决公文处理中的格式混乱、编号错漏等问题。支持标题层级自动编号、摘要生成、要素补全等功能,输出标准化Markdown格式。核心流程包括输入原文、智能识别、自动排版与要素输出,适用于通知、纪要等场景。实施需统一模板规则,规范输入格式,并通过试跑优化纠错率与处理效率。关键价值在于减少人工返工,提升排版一致性,未来可对接OA系统实现全流程自动化。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 472

linux select和poll系统调用源码分析

linux select内核实现原理: select系统调用定义,位置在\fs\select.c 在看linux内核对select实现之前,最好先了解用户态程序是怎么使用的,这样有利于我们对select实现的理解,select函数的使用可以自行上网搜索。 select系统调用格式定义如下: SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, fd_set __user *, exp, struct

zhangjianjun521的博客 391

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

深入理解Linux内核select多路复用原理

写在前面:本文以Linux2.6.0的内核源码进行讲解,使用x86 32位机讲解。 多路复用原理 讲多路复用的原理,那么一定先要讲没有多路复用的弊端。传统的阻塞式,进程一旦io读写就开始阻塞,效率太低,导致整个系统的吞吐量急剧下降。那么,就有人要思考,居然要阻塞,那么我就使用线程去阻塞,那么一个系统的io操作如此之多,要多少个线程才能满足呢?线程是不是会占用资源?当线程多起来后分时复用的CPU需要一直切换上下文,切换上下文是不是在浪费CPU资源呢,会导致大量的时间在切换上下文? 所以就引入了多路复用,把

李哈zzz的博客 1630

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

多路复用IO: select、sys_select、do_select源码分析

《srsLTE源码学习:逻辑信道多路复用与MAC CE分解pdu_queue.h,pdu_queue.cc》 《select用法》 《从select函数谈及系统调用原理》 《Linux Socket C语言网络编程:Select Socket》 《Linux Socket C语言网络编程:Poll Socket》 《Linux Socket C语言网络编程:Epoll Socket》 《浅谈epoll》 《什么是epoll的水平触发与边缘触发?》 《linux-io-multiplexin.

RToax 1243

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

select用法&原理详解(源码剖析)

最近刚接触Linux下的select用法,查阅了很多资料终于懂得了一丁点,故将自己查阅后有用的资料整理在这下面。博客链接都是很有价值,写的很好的文章。在研读源码时主要看的是这篇文章:深入select多路复用内核源码加驱动实现 自己能力精力有限,没有办法自己写一篇完完整整的文章,故只能当个搬运工了,文章先后顺序尽量按照了知识点的先后~~如果有什么问题欢迎一起探讨学习~ 前期知识 在开始接触s...

zhougb3的博客 7万+

select源码分析

select源码分析 select源码分析 select() core_sys_select do_select 总结 select() 函数是从SYSCALL_DEFINE5(select, ...)开始. 可以简单的将SYSCALL_DEFINEx理解为系统定义的系统函数, 如果想了解 SYSCALL_DEFINE 可以看一下. 具体的执行流程是 : 将时间定义从...

啦啦啦 1741

select模型linux实现代码

本文以完整的源码的方式介绍如何在Linux 2.6.25中实现select系统调用。 TAG: select模型 Linux 2.6.25中的select系统调用 主要有4个函数: sys_select:处理时间参数,调用core_sys_select。 core_sys_select:处理三个fd_set参数,调用do_select。 do_s...

weixin_33953249的博客 292

Linux内核-I/O多路复用[select]和I/O事件就绪通知源码分析

本文通过对select源码的探索,引出了socket创建,I/O事件就绪通知,时钟中断、tcp接收远端数据等机制的源码分析。

weixin_38597669的博客 1249
上一篇: websocket介绍
下一篇: 并查集算法
ylf13
博客等级 码龄16年 28粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值