【问题标题】:non-blocking write in cc语言中的非阻塞写入
【发布时间】:2016-11-17 10:26:22
【问题描述】:

我在网上阅读了一些关于套接字编程的资料。默认情况下,write() 处于阻塞状态。在某些材料中,write() 仅在套接字缓冲区已满时才会阻塞。其他一些资料说write() 被阻塞,直到用户缓冲区中的所有数据都已移动到系统缓冲区,这意味着如果没有足够的空间放置数据,write() 也会阻塞。我想知道如果 write() 设置为阻塞,哪个语句是正确的。

【问题讨论】:

  • 是哪个socket?窗户?
  • @o_weisman 感谢您的回复。 Linux 系统。
  • 我建议您将有问题的操作系统添加为标签。
  • Linux 手册页建议这将写入可以写入缓冲区的数据量,并在数据写入后返回,即使只有部分数据可以放入套接字缓冲区,但我相信这取决于特定系统/套接字的实际实现。
  • 你描述的阻塞write的两种行为听起来和我一样。你能详细说明一下会有什么不同吗?有没有你可以运行的实验来证明这种差异?

标签: c linux sockets posix


【解决方案1】:

在某些材料中,write() 仅在套接字缓冲区已满时才会阻塞。其他一些资料说 write() 被阻塞,直到用户缓冲区中的所有数据都移动到系统缓冲区,这意味着如果没有足够的空间放置数据,write() 也会阻塞。

我不清楚这些实际上是在说什么不同的东西。

首先,一个所谓的“系统缓冲区”就是另一个所说的“套接字缓冲区”,但它们是同一个东西。

其次,当第一条语句说“write() 仅在套接字缓冲区已满时阻塞”时,这应解释为“write() 仅在写入操作溢出(系统)缓冲区时阻塞”。这与“write() 被阻塞,直到用户缓冲区中的所有数据都已移动到系统缓冲区”相同;只是一个说条件会导致 write() 阻塞,另一个说一旦条件变为 false,块就会停止。这并不矛盾。

【讨论】:

    【解决方案2】:

    当描述符是套接字时,write 函数的行为类似于 send() 函数。如果内部缓冲区已满,write() 函数将阻塞,直到可以发送所有数据。这假定套接字是阻塞的。请记住,写函数可以被信号中断; errno 将设置为 EINTR(返回值将是捕获信号时写入的字节数),您可以再次调用 write() 直到发送所有数据。

    http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html http://pubs.opengroup.org/onlinepubs/009695399/functions/send.html

    【讨论】:

    • 在我上面发布的 send() 函数的链接上,它说如果发送套接字没有空间来保存要传输的消息,并且套接字文件描述符没有 O_NONBLOCK设置,send() 将阻塞,直到空间可用。所以也许这就是你正在寻找的答案。至于我写的“直到可以发送所有数据”,我的意思是说直到传递给 write() 函数的所有数据都写入内部缓冲区。我为措辞松懈而道歉,并不是有意误导您。
    猜你喜欢
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-25
    • 2011-03-10
    • 1970-01-01
    相关资源
    最近更新 更多