首先我们看下tcp_recvmsg的函数签名:
文章插图
显然我们关注焦点在(int nonblock这个参数上):
文章插图
上面的逻辑归结起来就是:
(1)在设置了nonblock的时候,如果copied>0,则返回读了多少字节,如果copied=0,则返回-EAGAIN,提示应用重复调用 。
(2)如果没有设置nonblock,如果读取的数据>=期望,则返回读取了多少字节 。如果没有则用sk_wait_data将当前进程等待 。
如下流程图所示:
文章插图
- 阻塞函数sk_wait_data
文章插图
该函数调用schedule_timeout进入睡眠,其进一步调用了schedule函数,首先从运行队列删除,其次加入到等待队列,最后调用和体系结构相关的switch_to宏来完成进程间的切换 。
如下图所示:
文章插图
- 阻塞后什么时候恢复运行呢
首先我们看下网络分组到来的内核路径,网卡发起中断后调用netif_rx将事件挂入CPU的等待队列,并唤起软中断(soft_irq),再通过linux的软中断机制调用net_rx_action,如下图所示:
文章插图
注:上图来自PLKA(<<深入Linux内核架构>>)
紧接着跟踪next_rx_action
文章插图
紧接着tcp_v4_rcv:
文章插图
在这里__wake_up_common将停在当前wait_queue_head_t中的进程唤醒,即状态改为task_running,等待CFS调度以进行下一步的动作,如下图所示 。
文章插图
情况2:设定的超时时间到来
在前面调用sk_wait_event中调用了schedule_timeout
文章插图
process_timeout函数即是将此进程重新唤醒
文章插图
原文链接:
https://my.oschina.net/alchemystar/blog/1791017
【从 Linux 源码看 Socket 的阻塞和非阻塞】
推荐阅读
- 宝宝讲话迟怎么办
- 光明牛奶蒙牛和伊利这三个牛奶哪个最好-从质量上看,伊利,蒙牛,光明哪个奶好-_1
- 从前一样窗前月,才有梅花便不同?梅花 白玉堂前一树梅,为谁零落为谁开
- 义和团杀了多少同胞?义和团反对的是谁
- 为何厨房用品一定要白色?
- 从小给孩子讲故事有什么好处?孩子喜欢听故事的好处
- 从血型看性格 四大血型性格分析
- Linux系统测试端口连通性的方法
- linux查看占用cpu最高的进程
- 11 个可以部署在 Linux 服务器上的开源论坛软件