Golang net.Conn并行写

时间:2016-07-25 10:44:17

标签: go network-programming

我有多个Goroutines共享一个net.Conn对象。他们可以同时发出写入呼叫吗?

我主要担心的是部分完成的写调用。假设我打算写100个字节,但只发送了30个字节,所以我需要再发送70个字节。为此,我通常会写一个循环:

count := 0
for count < len(buf) {
    byteSent, err := conn.Write(buf[count:])
    //check error 

    count += byteSent
}

但是我看到Go在net.Conn.Write行号318中实现了这个循环,它通过锁定来实现。

但是,在Windows实现时,除了调用WSASend之外没有这样的循环。我不知道WSASend的行为如何,也无法从MSDN文档中获得太多收益

因此问题是:

[edit]添加了第4个问题

  1. 每次写入socket都需要获取锁吗?
  2. 如果是,那么在Write实现中获取锁定的目的就会失败。
  3. 在unix实现中,是否意味着我无法获取byteSent&lt; len(buf)除非错误!= nil? (我的意思是我正在读代码吗?)
  4. Windows上的WSASend是否实现了Unix实现中的等效循环

2 个答案:

答案 0 :(得分:5)

是的,您可以并行调用net.Conn的写入方法。

net.Conn合同的一部分是它可以同时从多个Goroutines中使用。这在its documentation中明确提到:

  

Conn是一种通用的面向流的网络连接。

     

多个goroutine可以同时调用Conn上的方法。

虽然我不能特别谈到Windows实现,但这种说法适用于所有平台。由于Windows实现中没有循环,因此WSASend调用必须保证Unix API不会。

答案 1 :(得分:0)

  1. io.Write表示在部分写入的情况下,错误将是!= nil

  2. 在StackOverflow上找到here,WSASend不需要循环它。

  3. 来自#1&amp; #2,这意味着在调用net.Conn.Write之前我不需要获取锁。

  4. 所以我的问题得到了解答。