调度激活机制

晨曦之光 发布于 2012/04/10 15:06
阅读 241
收藏 0

Avoiding Blocking System Calls in a User-Level Threads Scheduler for Shared Memory Multiprocessors

这是我很早就下载的一个pdf文档,具体哪里下的忘了,特向作者致谢,这文档真的不错!题目我保留了,需要全文的朋友可以自己google,这篇文章我只翻译部分,略了很多,主要加上自己的想法。强烈建议阅读原文!
作者信息:
Andrew Borg
andborg@orbit.net.mt
University of Malta
June 26, 2001
摘要

smp近来大规模应用于并行计算,多线程被证明非常适合smp。程序员利用线程库编写多线程程序。线程库要么自己调度线程要么把调度任务交给操作系统内核。但是这两种方法都会引起一些问题。本文描述了两个用户级别的调度器,一个适于单cpu,一个适于smp。这些机制会使在执行阻塞系统调用时不会在内核 阻塞。为了实现这个目的,我们利用系统扩展里面一个叫做“调度激活”的机制。避免阻塞在那些需要同时处理很多客户端的服务器程序里非常有用。一个提供静态页面的web服务器也将从中受益。
1.引言
老版本的unix及类unix系统对多线程并发编程支持的很不让人满意。这些使得设计并行应用非常困难。多线程在很多并行编程中是同时协同过程的容器。
传统意义的线程被分为内核线程和用户线程。用户线程的主要优势就是高效,它的调度核心在用户空间实现。内核线程就不那么高效了,它需要内核来提供调度机制。这篇论文里面,我们提供一个调度激活机制来对用户线程提供内核级别的支持。通过这种犯法,用户线程保持着它的高效,并且调度核心仍然在用户空间。
2.背景
2.1.从进程到内核线程
线程的概念在1965年就有了。在那时它们不叫线程,而叫进程。
   unix下进程的概念就是一个执行绪(线程)加上一个地址空间。因此,unix下的进程是重量的。
重量级的进程只是实现了粗粒度的并行,这就导致了线程的产生,线程仅仅是一个和别的线程共享地址空间的传统unix进程,它们也被叫做轻量级进程。轻量级 进程往往被认为是内核线程,因为内核负责它们的创建,销毁,同步,调度。内核既然已经可以看到轻量级进程,那么所有可以用于进程的概念就可以用于轻量级进程即内核线程了。
2.2.从内核线程到用户线程
内核线程主要不好的地方在于它受制于内核提供的机制。主要就是说用户程序无法享用自己的调度策略,内核怎么调度全看内核怎么实现。内核线程虽然和进程相比轻量了很多,但和用户线程比较起来还是过于重量了。
  ...
当应用程序实现用户线程时那么线程被用户程序自己管理。这样就可以选择不同调度策略来应用于不同需求的应用程序。用户线程非常高效,上下文切换高效得多,内核完全不必介入。内核线程虽然比进程好了很多,但还是比不过用户线程。
2.3.用户线程的问题
由于用户线程不被大多数操作系统内核有效支持,那么把已经在内核线程集成的服务集成到用户线程就很困难。由于内核根本看不到用户线程,那么就引起两个很棘手的问题:
      a.调度问题
      b.阻塞问题
对于a,内核很有可能调度一个低优先级的县城而放弃高优先级的,另外,如果一个用户线程持有锁,抢占它并不是一个好主意。对于b,当一个用户线程引起阻塞系统调用时,内核不会通知用户线程。
2.4.阻塞系统调用
本部分主要说如果一个用户线程阻塞在内核了,那么用户的不到任何通知,这样整个进程就全部阻塞了。
3.调度激活
这部分描述当阻塞调用时,调度激活是怎么应对的。
3.1.调度激活背后的思想
调度激活使得当内核觉得要调度用户线程时会通知用户线程。在内核里面相关的内核事件会导致用户线程调度器重新决定调度事宜,决定哪个线程应该运行在哪个虚拟cpu上。这个机制通过引进一个新的名叫upcall的系统调用来实现。upcall是一个内核到应用的调用,和传统的应用调用内核服务的 downcall相反。内核就是利用调度激活来实现upcall的,一个调度激活是一个和传统内核线程一样的执行环境上下文。事实上,调度激活在好多系统 的实现正是利用了内核线程,只是加上了upcall。在传统的内核线程,都要指派给它自己一个函数,然后交给操作系统运行,调度激活正好相反,它是操作系 统觉得要用调度激活时,就会先创建一个调度激活,然后开始运行一个事先指定好的用户函数。(待续)


原文链接:http://blog.csdn.net/dog250/article/details/5302737
加载中
返回顶部
顶部