Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang net.Conn Write in parallel

I have multiple Goroutines sharing a net.Conn object. Can they issue a Write calls simultaneously?

My main concern is that of Write calls which are partially done. Say I intend to wrote 100 bytes, but only 30 were sent, so I need to send 70 more. For this I will typically write a loop:

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

    count += byteSent
}

But I see that Go implements this loop in net.Conn.Write line number 318 and it does so by taking a lock.

However, on Windows implementation there is no such loop except that there is a call to WSASend. I do not know how WSASend behaves and could not get much from the MSDN docs

Hence the questions are:

[edit] Added 4th question

  1. Do I need to acquire a lock everytime I write to socket?
  2. If yes, then the purpose of acquiring the lock in Write implementation is defeated.
  3. In unix implementation, does it mean that I cannot get byteSent < len(buf) unless err != nil? (I mean am I reading the code correct?)
  4. Does the WSASend on Windows implements the equivalent loop in Unix implementation
like image 647
bitflood Avatar asked Jul 25 '16 10:07

bitflood


2 Answers

Yes, you can make many calls to a net.Conn's write method in parallel.

Part of net.Conn's contract is that it can be used from multiple Goroutines concurrently. This is explicitly called out in its documentation:

Conn is a generic stream-oriented network connection.

Multiple goroutines may invoke methods on a Conn simultaneously.

Though I can't speak to the Windows implementation in particular, this statement holds true for all platforms. Since there is no loop in the Windows implementation then WSASend calls must make guarantees that the Unix API does not.

like image 153
Sam Whited Avatar answered Oct 02 '22 00:10

Sam Whited


  1. The io.Write says that in case of partial write, err will be != nil

  2. Found here on StackOverflow that WSASend need not have a loop around it.

  3. From #1 & #2, it implies that I need not acquire lock before calling net.Conn.Write.

So my question stands answered.

like image 45
bitflood Avatar answered Oct 02 '22 01:10

bitflood