Multithreading 多个goroutine是否会同时调用Conn上的方法?

Multithreading 多个goroutine是否会同时调用Conn上的方法?,multithreading,networking,go,goroutine,Multithreading,Networking,Go,Goroutine,我的程序是这样的: func handle(conn net.Conn) { msg := "hello, world!" for i:= 0; i< 100000; i++ { go func() { err := write(conn, msg) } } } func write(conn net.Conn, msg string) error { mlen := fmt.Sprintf("%04

我的程序是这样的:

func handle(conn net.Conn) {
    msg := "hello, world!"
    for i:= 0; i< 100000; i++ {
        go func() {
            err := write(conn, msg)
        }
    }

}
func write(conn net.Conn, msg string) error {
    mlen := fmt.Sprintf("%04d", len(msg))

    _, err := conn.Write([]byte(mlen + msg))
    return err
}
func句柄(conn net.conn){
msg:=“你好,世界!”
对于i:=0;i<100000;i++{
go func(){
错误:=写入(连接,消息)
}
}
}
func写入(conn net.conn,msg字符串)错误{
mlen:=fmt.Sprintf(“%04d”,len(msg))
_,err:=conn.Write([]字节(mlen+msg))
返回错误
}
该程序将同时运行100000个goroutine,所有goroutine将向同一连接发送消息 我怀疑服务器是否会收到类似“hellohelloworldworld”的错误消息,但当程序在我的Ubuntu14.04LTS中运行时没有问题

那么,多个goroutine会同时调用Conn上的一个方法吗

=========================================================================


如何使
Write
方法保持原子性?

文档说明:

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

没有提到每个单独的写入是否是原子的。虽然当前的实现可以确保每次调用
Write
都在下一次调用开始之前完成,但语言规范中没有任何保证

这意味着写入是原子的

具体地说,如果发生部分写入,io.Write接口的实现者需要返回错误。net.Conn在unix上通过获取锁并在循环中调用write来处理此问题,直到写入整个缓冲区。在Windows上,它调用WSASend,它保证发送整个缓冲区,除非发生错误。但这些文件确实:

调用WSASend的顺序也是 缓冲区被传输到传输层。WSASend不应该是 在同一个面向流的套接字上从不同的 线程,因为某些Winsock提供程序可能会拆分大型发送请求 进入多个传输,这可能会导致意外数据 在同一台计算机上交错多个并发发送请求 面向流的套接字

这意味着它不一定是原子的,除非Go获得互斥锁-

所以基本上它是原子的。可以想象,一个实现可以将线程安全定义为不崩溃,通过解锁写调用周围的互斥锁(或者根本不在windows上获取互斥锁)来允许交叉写,但这对我来说没有意义,而且开发人员已经清楚地表明了相反的意图