linux – 当* exact *是一个准备写入的套接字?
当应用程序有大量数据(400M)写入非阻塞套接字时,write()会在发送缓冲区变满时返回EWOULDBLOCK或EAGAIN.
当(e)轮询套接字时,我有时会在发送缓冲区中有7M空间时看到写入就绪通知,有时是20M,有时是1M.写就绪回调之间的延迟变化很大:从几毫秒到几十秒! 所以我的问题是内核何时触发了套接字的写就绪?是什么影响了写入就绪的触发?显然,只要将1B写入电线,就不会触发它. 任何帮助,将不胜感激! 我正在使用: Ubuntu 12.04 LTS 内核3.8.0-39-通用 Arch:x86_64 编辑:此上下文中的套接字是TCP / IP套接字. 解决方法
TL;博士;只要你的套接字有足够的缓冲区空间写入成功,epoll_wait就会在默认的级别触发模式下返回事件.如果套接字空间不足,阻塞编写器将会休眠.当数据被确认释放空间时,内核将唤醒进程(或传递epoll事件以表示套接字是可写的),但仅当套接字空间不足时.就像以前一样,只要套接字是可写的,没有任何变化,即使没有来自TCP的新通知,也会涌入级别触发的事件. 执行实际通知的函数是sk_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); ... 此函数唤醒可能正在等待内存的任何调用者. 但什么时候调用sk_write_space?有一些调用站点,但最突出的是tcp_new_space,它由tcp_check_space调用,由tcp_data_snd_check调用,该调用是从接收路径上的一堆地方调用的.功能has a descriptive comment:
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检查并清除它. 所有这些的结论是tcp_check_space避免发送事件,除非套接字空间不足. 那么tcp_data_snd_check呢?在稳定状态期间,最相关的调用是在tcp_rcv_established中: >快速路径: 所有这些信号数据都已成功确认. TCP中还有其他sk_write_space调用者. do_tcp_sendpages和tcp_sendmsg_locked在错误路径上调用它以确保调用者被唤醒. do_tcp_setsockopt在设置TCP_NOTSENT_LOWAT时调用它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |