加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 当* exact *是一个准备写入的套接字?

发布时间:2020-12-14 01:39:13 所属栏目:Linux 来源:网络整理
导读:当应用程序有大量数据(400M)写入非阻塞套接字时,write()会在发送缓冲区变满时返回EWOULDBLOCK或EAGAIN. 当(e)轮询套接字时,我有时会在发送缓冲区中有7M空间时看到写入就绪通知,有时是20M,有时是1M.写就绪回调之间的延迟变化很大:从几毫秒到几十秒! 所以我
当应用程序有大量数据(400M)写入非阻塞套接字时,write()会在发送缓冲区变满时返回EWOULDBLOCK或EAGAIN.

当(e)轮询套接字时,我有时会在发送缓冲区中有7M空间时看到写入就绪通知,有时是20M,有时是1M.写就绪回调之间的延迟变化很大:从几毫秒到几十秒!

所以我的问题是内核何时触发了套接字的写就绪?是什么影响了写入就绪的触发?显然,只要将1B写入电线,就不会触发它.

任何帮助,将不胜感激!

我正在使用:

Ubuntu 12.04 LTS

内核3.8.0-39-通用

Arch:x86_64

编辑:此上下文中的套接字是TCP / IP套接字.

解决方法

So my question is when exactly does the kernel trigger a write-ready for a socket?

TL;博士;只要你的套接字有足够的缓冲区空间写入成功,epoll_wait就会在默认的级别触发模式下返回事件.如果套接字空间不足,阻塞编写器将会休眠.当数据被确认释放空间时,内核将唤醒进程(或传递epoll事件以表示套接字是可写的),但仅当套接字空间不足时.就像以前一样,只要套接字是可写的,没有任何变化,即使没有来自TCP的新通知,也会涌入级别触发的事件.

执行实际通知的函数是sk_write_space.
这是struct sock的成员,对于TCP,相关的实现是stream.c中的sk_stream_write_space.

...
    if (skwq_has_sleeper(wq))
        wake_up_interruptible_poll(&wq->wait,EPOLLOUT |
                    EPOLLWRNORM | EPOLLWRBAND);
    if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
        sock_wake_async(wq,SOCK_WAKE_SPACE,POLL_OUT);
    ...

此函数唤醒可能正在等待内存的任何调用者.
(与此比较sock_def_write_space.

但什么时候调用sk_write_space?有一些调用站点,但最突出的是tcp_new_space,它由tcp_check_space调用,由tcp_data_snd_check调用,该调用是从接收路径上的一堆地方调用的.功能has a descriptive comment:

06001

tcp_check_space很有趣:

if (sock_flag(sk,SOCK_QUEUE_SHRUNK)) {
        sock_reset_flag(sk,SOCK_QUEUE_SHRUNK);
        /* pairs with tcp_poll() */
        smp_mb();
        if (sk->sk_socket &&
            test_bit(SOCK_NOSPACE,&sk->sk_socket->flags)) {
            tcp_new_space(sk);
            ...
        }

这里有一些相关内容:

> SOCK_QUEUE_SHRUNK定义为“写队列最近已收缩”并在发送路径上设置. tcp_check_space检查并清除它.
>当我们用完缓冲区空间时,SOCK_NOSPACE在发送路径上设置.

所有这些的结论是tcp_check_space避免发送事件,除非套接字空间不足.

那么tcp_data_snd_check呢?在稳定状态期间,最相关的调用是在tcp_rcv_established中:

>快速路径:
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_input.c#L5575
>几乎快速的道路:
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_input.c#L5618
>慢路径:
https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_input.c#L5658

所有这些信号数据都已成功确认.

TCP中还有其他sk_write_space调用者. do_tcp_sendpages和tcp_sendmsg_locked在错误路径上调用它以确保调用者被唤醒. do_tcp_setsockopt在设置TCP_NOTSENT_LOWAT时调用它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读