4

系统调用是否完全在软件中断处理程序的上下文中执行?

我的意思是,像 read() 这样的一些系统调用可能需要很长时间才能返回,这违反了 ISR 的执行时间应该非常短的策略。系统调用是否已卸载到其他线程?这是如何运作的?

[对任何内核的引用都可以]

4

3 回答 3

3

系统调用在ISR内的大多数内核上运行。快速浏览一下 Linux 的早期版本,您会注意到int $Ox80调用内核的方法。从内核开发的角度来看,这个可能是最简单的解决方案有一个很大的缺点:只要运行 ISR;中断被禁用。禁用中断太长时间很糟糕,因为很明显您的系统不会反应(它会延迟外部事件,它不会按时重新安排......)。

正如 Adel 在他的回答中解释的那样,抢占是一个聪明的解决方案。但是每当内核因为资源不可用而选择抢占线程时,它通常已经花费了大量时间来禁用中断。

系统调用是否已卸载到其他线程?

你是对的。中断线程和/或线程内核是一个更智能的解决方案。像 Solaris 和 Mac OS X 这样的内核更喜欢有非常简单的 ISR,它只是唤醒高优先级的中断线程。因此,ISR 被减少到最少的处理,并且系统在中断禁用的情况下运行的时间大大减少。因为这些中断线程具有高优先级,所以它们很可能在 ISR 返回时运行。好的是中断将再次启用,因此更高优先级的工作不会被延迟。使用线程内核,例如最近发布的 Linux,可以在内核内部完成多项操作,尽管有一个块,其他进程仍然能够进入内核。

希望这有帮助!

于 2012-06-16T08:54:44.427 回答
3

请阅读系统调用正常工作方式的引用文本:

当用户程序启动系统调用时,系统调用处理程序获得控制权。系统调用处理程序将保护域从调用者保护域用户更改为系统调用保护域内核,并切换到受保护的堆栈。

然后系统调用处理程序调用支持系统调用的函数。加载器为此目的维护一个当前定义的系统调用表。

系统调用在调用进程中运行,但比调用进程具有更多特权。这是因为保护域已从用户更改为内核。

系统调用函数在执行完操作后返回到系统调用处理程序。然后系统调用处理程序恢复进程的状态并返回给用户程序。

现在,关于系统调用期间的上下文切换,有两种类型的内核。抢占式和非抢占式内核(粗略地说;因为这有时也适用于执行关键代码部分的线程/进程)。

前者在 RTOS(实时操作系统)中很常见,而后者在我们所知道的最常见的操作系统中很常见。
在抢占式内核中,调度程序可以选择退出执行系统调用的线程,以支持具有更高优先级的线程。后者不允许这种抢占,如;如果一个线程当前正在执行系统调用,所有其他线程都应该等到它完成其内核模式工作。

总结一下,通常在非 RT 系统中,如果一个线程执行系统调用,它应该在被调度之前完成它的工作。

现在注意一些事情,一些系统调用可能会阻塞
这是什么意思?这意味着他们将停止直到发生中断,然后他们将重新执行直到他们完成他们的工作。
一个例子是 read(),它会阻塞直到用户请求的数据准备好;同时,可以安排其他线程运行,但是一旦中断到达该 read() 它将再次开始运行,并且没有人可以调度它(再次,仅在非抢占式环境中),直到它返回给用户登陆结果。

于 2012-06-11T23:27:04.157 回答
1

首先,Linux 中使用的一些术语。在 Linux 中,内核可以在多种情况下运行:

  • 进程上下文(用户上下文):内核代表用户空间进程运行,它调用了系统调用,正在读取/proc文件,...
  • 中断上下文:内核在响应某些中断时运行。
  • 原子上下文:内核由于某种原因无法休眠(阻塞):可能它在中断上下文中运行,或者某些自旋锁被锁定,...
  • 非原子上下文:很明显,我希望。

系统调用在启用中断的情况下开始执行(或者因为它们被明确地重新启用(例如:当使用 x86 时sysenter),或者因为它们根本没有被禁用(例如:当使用 x86 的陷阱门时,Linuxint 0x80会这样做))。因此,内核在执行系统调用时可能会被中断中断。

一些系统调用可能会休眠(阻塞),等待某些东西。在这种情况下,内核可以切换到另一个任务(进程/线程),休眠的任务稍后会被唤醒。

在非抢占式内核中,一个任务不能抢占另一个在进程上下文中正在运行(即实际工作,而不是休眠)的任务。在抢占式内核中,较高优先级的任务可以抢占在非原子进程上下文中运行的较低优先级的任务。这可以防止高上下文切换延迟,例如:音频程序可能需要非常频繁地调度,抢占式内核可以防止其他任务的繁重系统调用处理与此混淆(否则可能导致音频伪影、点击……)

于 2012-06-16T10:35:17.310 回答