2016-07-25 250 views
2

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

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

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

    count += byteSent 
} 

但我看到的围棋net.Conn.Write行号318实现了这个循环,并通过采取锁这样做。

但是,在Windows实现中,除了调用WSASend之外,没有这样的循环。我不知道WSASend的行为,不能从MSDN文档

得到多少因此,问题是:

[编辑]新增4问题

  1. 我需要获得锁,每次我写入套接字?
  2. 如果是,则在Write实现中获取锁定的目的被破坏。
  3. 在unix实现中,是否意味着我无法获取byteSent < len(buf)除非err!= nil? (我的意思是我阅读的代码是否正确?)
  4. 是否在Windows上的WSASend实现了UNIX的等效回路
+0

该文档声明:“多个goroutines可能同时调用Conn上的方法。”如果这不适用于所有平台,那么这是一个需要修复的错误。 – JimB

+0

你说得对。阻止我提交bug的唯一方法是我不知道WSASend是否实现了与unix impl等效的循环。因此SO – user2248790

+0

上的问题通常情况下,如果您证明它无法正常工作,则会发出错误。否则,您认为代码按照广告方式工作。 – JimB

回答

0
  1. io.Write说,在部分写的情况下,ERR会!=零

  2. 在计算器上发现here是WSASend不必周围有一个循环。

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

所以我的问题得到解答。

4

是的,你可以多次调用并行net.Conn“s的写入方法。

net.Conn的部分合同是它可以同时用于多个Goroutine。这明确地在its documentation中提出:

conn是一个通用的面向流的网络连接。

多个goroutines可能同时调用Conn上的方法。

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