关于多线程:放弃CPU控制的线程-在教科书中发现矛盾

Threads giving up CPU control - Seeming contradiction in textbook

我正在学习操作系统课程中的线程和进程,并且在我的教科书(《现代操作系统》,Tanenbaum和Bos第四版)中遇到了明显的矛盾。我敢肯定,这里有些东西我会误解,如果有人可以清理清楚,那就太好了。

在第106页上:

Another common thread call is thread_yield, which allows a thread to voluntarily give up the CPU to let another thread run. Such a call is important because there is no clock interrupt to actually enforce multiprogramming as there is with processes

好吧-所以我的解释是,线程永远不会放弃控制权,除非他们愿意让步。很有道理。

然后在第116页上,在线程对共享信息进行错误处理的示例中:

As an example, consider the errno variable maintained by UNIX. When a process (or a thread) makes a system call that fails, the error code is put into errno. In Fig. 2-19, thread 1 executes the system call access to find out if it has permission to access a certain file. The operating system returns the answer in the global variable errno. After control has returned to thread 1, but before it has a chance to read errno, the scheduler decides that thread 1 has had enough CPU time for the moment and decides to switch to thread 2.

但是线程1只是不是非自愿地从CPU中拉出来的吗?我以为没有办法像进程切换那样强制执行线程切换?


混淆之处在于有两种不同的方式实现线程。在过去,根本没有线程支持。 DoD对Ada编程语言的要求(其中的任务(即线程)是必不可少的一部分)强制采用线程。

运行时库已创建(主要是为了支持Ada)。这在一个过程中起作用。该进程维护一个计时器,该计时器将中断线程,并且库将在线程之间切换,就像操作系统切换进程一样。

请注意,即使在多处理器系统上,此系统一次也只允许一个进程的一个线程执行。

您的第一个示例描述了这样的库,但它描述了非常原始的线程库,其中线程调度基于进程各个线程之间的协作。

后来,操作系统开始开发对线程的支持。操作系统不是调度进程,而是调度线程以供执行。进程就是具有线程集合的地址空间。您的第二个示例正在讨论这种线程。


如果我们要使用进程级线程而不是OS级线程,则这很有意义。 CPU可以中断一个进程(无论运行什么线程),但是由于OS不知道进程级线程,因此它无法中断它们。如果进程中的一个线程要允许另一个线程运行,则必须专门屈服于另一个线程。

但是,如今,大多数语言都使用操作系统级别的线程,操作系统确实知道这些线程并且可以抢占这些线程。