Go internal/poll/fd_unix.go 代码在这里// Write implements io.Writer.func (fd *FD) Write(p []byte) (int, error) { if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() ......}java代码java.net.SocketOutputStream#socketWrite在这里 private void socketWrite(byte b[], int off, int len) throws IOException { if (len <= 0 || off < 0 || len > b.length - off) { if (len == 0) { return; } throw new ArrayIndexOutOfBoundsException("len == " + len + " off == " + off + " buffer length == " + b.length); } FileDescriptor fd = impl.acquireFD(); try { socketWrite0(fd, b, off, len); } catch (SocketException se) { ......我不知道为什么我们需要锁定它。另一个问题是 syscall.Write 等效于 <unistd.h> 用 C 编写吗?
2 回答

婷婷同学_
TA贡献1844条经验 获得超8个赞
好吧,只回答 Java 部分:
既然我们已经在讨论实现细节,为什么要停留在 Java 级别呢?本机方法socketWrite0的 OpenJdk 实现的 C 源代码跨越约 70 行代码,显然不是原子的。它使用malloc
and执行分配和释放内存free
等操作,并且涉及相当多的非平凡逻辑。在那个时候,它调用的用于实际发送数据的函数是否NET_Send
直接转换为每个支持的平台上的系统调用都不再重要了。
要点是:实现NET_Send
在循环中调用 this -function。因此,无论这是否是单独的线程安全的,如果它被多个线程同时调用,输出将是交错的(最好的情况)。

慕码人2483693
TA贡献1860条经验 获得超9个赞
好的,假设没有锁定机制,并且两个并发线程/进程正在向套接字写入一些数据。让我们举一个过于简单的例子。
Java 应用程序想要写:“你好!你好吗?”。
Go 应用想写:“再见。”
这两个应用程序都试图同时写入。
您期望的输出是:
Hello! How are you?
See you later.
但是,您很有可能会得到类似的东西。
HellSee o! How See you are later.
you?
每当资源在不同的进程/线程之间共享并且没有适当的锁定机制时。遇到不一致和意外行为的可能性很高。
- 2 回答
- 0 关注
- 156 浏览
添加回答
举报
0/150
提交
取消