当前位置: 首页 > 知识库问答 >
问题:

关于阻塞系统调用和潜在竞争条件

轩辕越泽
2023-03-14

我们正在对网络套接字使用阻塞系统I/O调用。我们想要的行为是当对套接字调用close()时,阻塞调用需要返回并抛出一个异常(引用),

看看OpenJDK,这就是它的实现方式。它使用用户信号唤醒阻塞线程。相应的信号处理程序是no-op。在阻塞调用之前,它注册可能被阻塞的线程。当关闭文件描述符时,关闭线程向阻塞的I/O线程发送信号,这导致阻塞调用返回eintr

不过,我还是认为下面的代码块源代码中存在一个潜在的竞争条件:

  startOp(fdEntry, &self);  // (1)
  ret = FUNC;               // (2)
  endOp(fdEntry, &self); 

在I/O线程中,(1)执行,然后关闭线程调用close并在(2)开始执行之前将信号发送给I/O线程。接收并丢弃该信号。当(2)开始在I/O线程中执行时,它将进行阻塞系统调用。在这个阶段,fdEntry可能关闭,或者即将关闭。

我理解对吗?是我做了一个错误的观察,还是种族状况的可能性很低,所以我们可以放心地忽略它?

共有1个答案

杨景山
2023-03-14

回答自己:原来它确实是一个bug。修复是在close端:我们首先关闭文件描述符,然后通知阻塞线程。如果阻塞线程错过信号并启动阻塞调用,它将立即以ebadf返回,因为文件描述符已经关闭。

 类似资料:
  • 我遇到了这段代码,它使用Java流,特别是parallelStream(),以便从oracle数据库收集一些数据。见下文,在这种情况下: 范围=一些输入Id列表 据我所知,这是如何工作的: 将范围拆分为1000个块以输入函数 处理线程中的每个块以返回一些结果 将结果汇总到POJO列表中 我的问题是试图减少到单个列表中所带来的潜在竞争条件。这些线程中的许多是否有可能尝试将内容添加到结果列表中并可能损

  • 我已经编写了一个计时器,它将测量任何多线程应用程序中特定代码的性能。在下面的计时器中,它还将用x毫秒的调用次数填充映射。我将使用这个图作为我的直方图的一部分来做进一步的分析,比如调用的百分比花费了这么多毫秒等等。 例如,这是我将使用上面的计时器类来衡量多线程应用程序中特定代码的性能的方式: 现在我的问题是,如果你看一下getDuration方法,我也会在我的地图中填充一些信息,比如花了x毫秒的调用

  • 9.1. 竞争条件 在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序,x是在y之前还是之后还是同时发生是没法

  • 9.6. 竞争条件检测 即使我们小心到不能再小心,但在并发程序中犯错还是太容易了。幸运的是,Go的runtime和工具链为我们装备了一个复杂但好用的动态分析工具,竞争检查器(the race detector)。 只要在go build,go run或者go test命令后面加上-race的flag,就会使编译器创建一个你的应用的“修改”版或者一个附带了能够记录所有运行期对共享变量访问工具的tes

  • 我完全混淆了,,。 哪个是阻塞,哪个不是? 我的意思是如果我使用父进程是否等待子进程返回/才继续执行。 如何影响这些调用?