【问题标题】:should system calls be completed before context switch系统调用是否应该在上下文切换之前完成
【发布时间】:2018-07-30 04:39:16
【问题描述】:

是否保证系统调用在上下文切换或抢占之前完成?我们是否应该期望系统调用指令是不可中断的。还是取决于系统调用类型或操作系统实现?

【问题讨论】:

  • 相反,系统调用往往会触发上下文切换,假设系统调用阻塞等待某个事件。
  • 是否可以中断系统调用块执行?
  • @RedArrow 没有。正确的方法是使用系统调用的非阻塞版本。在这种情况下,这些系统调用会立即将控制权返回给调用程序,并带有错误代码,例如 EWOULDBLOCK。
  • 共享资源受到保护的方式是一次只允许一个进程访问共享资源。这不会阻止“拥有”共享资源的进程被抢占。这只是意味着另一个想要使用该资源的进程必须等待。
  • @RedArrow,您应该先拨打tour,阅读How to Askminimal reproducible example,然后再在这里提问。所以看起来你真正想要的是关于你的标准库和操作系统函数的线程安全的信息,这真的取决于实现。

标签: c linux operating-system posix


【解决方案1】:

是否保证系统调用会在上下文切换或抢占之前完成

不,许多系统调用实际上会导致上下文切换发生,即使在单线程应用程序中也是如此。我们不要忘记,当今大多数现代系统上还运行着其他进程,此外还有硬件中断和大量异步事件。

还是取决于系统调用类型或操作系统实现?

是的,非常喜欢。

如果那些系统调用线程安全,有什么保证?

阅读您的系统文档。

大多数 C 编译器工具链包括单线程和多线程库。即使是单线程库也是上下文切换安全的,但不一定可以从同一个进程重新进入。上下文切换就是这样,将当前线程的整个上下文切换为新的。只要这些线程没有触及任何共享资源(上下文重叠),就没有其他需要关注的了。但是,当您编写多线程应用程序时,您必须对您拥有的线程之间共享的资源负责。在大多数情况下,好的设计会避免共享资源,但也有不可避免的关键路径。

大多数现代操作系统都有许多内部共享资源,它们使用各种技术来同步对这些资源的访问。锁、信号量、临界区、原子操作(无锁算法)都是多线程环境中的常见做法。应用程序编写者不必担心操作系统如何在内部管理对共享资源的访问,因此您可以从您的应用程序中调用openreadwrite,无需担心,前提是您之间不共享任何句柄进程中的线程。

当您编写多线程应用程序时,您应该使用编译器工具链提供的线程安全库。线程安全库使用与操作系统相同的所有技术来保护内部共享资源,但它们无法保护您免受您自己的伤害!如果您在线程之间共享资源,例如全局变量、句柄、缓冲区,甚至对某些硬件寄存器的访问,您必须安排同步这些访问。

操作系统编写者负责保护他们自己的内部共享资源并记录所有线程安全问题。

库编写者负责保护他们自己的内部共享资源并记录所有线程安全问题。

应用程序编写者负责保护他们自己的共享资源并记录所有进程并发问题(进程间资源共享)。

【讨论】:

    【解决方案2】:

    没有。假设您正在等待套接字读取完成。这可能需要几秒钟。现在,如果您的单核 cpu 是多任务的,您希望它在等待时运行其他线程。

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 2020-11-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2016-11-06
      相关资源
      最近更新 更多