为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

内核栈 系统调用

2018-04-01 20页 doc 38KB 16阅读

用户头像

is_729658

暂无简介

举报
内核栈 系统调用内核栈 系统调用 查看文章 内核态和用户态区别2008-07-26 12:07当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程...
内核栈 系统调用
内核栈 系统调用 查看文章 内核态和用户态区别2008-07-26 12:07当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。这与处于内核态的进程的状态有些类似。 1、用系统调用时进入核心态。Linux对硬件的操作只能在核心态,这可以通过写驱动程序来控制。在用户态操作硬件会造成core dump. 2、要注意区分系统调用和一般的函数。系统调用由内核提供,如read()、write()、open()等。而一般的函数由软件包中的函数库提供,如sin()、cos()等。在语法上两者没有区别。 3、一般情况:系统调用运行在核心态,函数运行在用户态。但也有一些函数在内部使用了系统调用(如fopen),这样的函数在调用系统调用是进入核心态,其他时候运行在用户态。 大概是当用户程序调用系统的API时,就产生中断,进入内核态的API,处理完成后,用中断再退出,返回用户态的调用函数。 user api--interrupt--kernel api--interrupt --- 简单来讲一个进程由于执行系统调用而开始执行内核代码,我们称该进程处于内核态中.一个进程执行应用程序自身代码则称该进程处于用户态. intel x86架构的CPU分为好几个运行级别,从0--3,0为最高级别,3为最低级别 针对不同的级别,有很多的限制,比如说传统的in,out指令,就是端口的输入输出指令,在0级下是可以用的,但在3级下就不能用,你用就产生陷阱,告诉你出错了,当然限制还有很多了,不只是这一点 操作系统下是利用这个特点,当操作系统自己的代码运行时,CPU就切成0 当用户的程序运行是就只让它在3级运行,这样如果用户的程序想做什么破级, 坏系统的事情的话,也没办法做到 当然,低级别的程序是没法把自己升到高级别的,也就是说用户程序运行在3级,他想把自己变成0级自己是做不到的,除非是操作系统帮忙,利用这个特性, 确保系统的安全了.平时把操作系统运操作系统就可以控制所有的程序的运行, 行时的级别就叫内核态(因为是操作系统内核运行时的状态),而且普通用户程序 运行时的那个级别叫用户态. 当操作系统刚引导时,CPU处于实模式,这时就相当于是0级,于是操作系统就自动得到最高权限,然后切到保护模式时就是0级,这时操作系统就占了先机,成为了最高级别的运行者,由于你的程序都是由操作系统来加载的,所以当它把你加载上来后,就把你的运行状态设为3级,即最低级,然后才让你运行,所以没办法,你只能在最低级运行了,因为没办法把自己从低级上升到高级,这就是操作系统在内核态可以管理用户程序,杀死用户程序的原因. 1.用户态和内核态的概念区别 究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例子 void testfork(){ if(0==fork()){ printf("create new process success~\n"); } printf("testfork ok\n"); } 这段代码很简单,从功能的角度来看,就是实际执行了一个fork(),生成一个新的进程,从逻辑的角度看,就是判断了如果fork()返回的是0则打印相关语句,然后函数最后再打印一句示执行完整个testfork()函数。代码的执行逻辑和功能上看就是如此简单,一共四行代码,从上到下一句一句执行而已,完全看不出来哪里有体现出用户态和进程态的概念。 如果说前面两种是静态观察的角度看的话,我们还可以从动态的角度来看这段代码,即它被转换成CPU执行的指令后加载执行的过程,这时这段程序就是一个动态执行的指令序列。而究竟加载了哪些代码,如何加载就是和操作系统密切相关了。 2)特权级 熟悉Unix/Linux系统的人都知道,fork的工作实际上是以系统调用的方式完成相应功能的,具体的工作是由sys_fork负责实施。其实无论是不是Unix或者Linux,对于任何操作系统来说,创建一个新的进程都是属于核心功能,因为它要做很多底层细致地工作,消耗系统的物理资源,比如分配物理内存,从父进程拷贝相关信息,拷贝设置页目录页表等等,这些显然不能随便让哪个程序就能去做,于是就自然引出特权级别的概念,显然,最关键性的权力必须由高特权级的程序来执行,这样才可以做到集中管理,减少有限资源的访问和使用冲突。 特权级显然是非常有效的管理和控制程序执行的手段,因此在硬件上对特权级做了很多支持,就Intel x86架构的CPU来说一共有0~3四个特权级,0级最高,3级最低,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查,相关的概念有CPL、DPL和RPL,这里不再过多阐述。硬件已经提供了一套特权级使用的相关机制,软件自然就是好好利用的问题,这属于操作系 统要做的事情,对于Unix/Linux来说,只使用了0级特权级和3级特权级。也就是说在Unix/Linux系统中,一条工作在0级特权级的指令具有了CPU能提供的最高权力,而一条工作在3级特权级的指令具有CPU提供的最低或者说最基本权力。 3)用户态和内核态 现在我们从特权级的调度来理解用户态和内核态就比较好理解了,当程序运行在3级特权级上时,就可以称之为运行在用户态,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当程序运行在0级特权级上时,就可以称之为运行在内核态。 虽然用户态下和内核态下工作的程序有很多差别,但最重要的差别就在于特权级的不同,即权力的不同。运行在用户态下的程序不能直接访问操作系统内核数据结构和程序,比如上面例子中的testfork()就不能直接调用sys_fork(),因为前者是工作在用户态,属于用户态程序,而sys_fork()是工作在内核态,属于内核态程序。 当我们在系统中执行一个程序时,大部分时间是运行在用户态下的,在其需要操作系统帮助完成某些它没有权力和能力完成的工作时就会切换到内核态,比如testfork()最初运行在用户态进程下,当它调用fork()最终触发sys_fork()的执行时,就切换到了内核态。 2.用户态和内核态的转换 1)用户态切换到内核态的3种方式 a.系统调用 这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如前例中fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。 b.异常 当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。 c.外围设备的中断 当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。 这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。 2)具体的切换操作 从触发方式上看,可以认为存在前述3种不同的类型,但是从最终实际完成由用户态到内核态的切换操作上来说,涉及的关键步骤是完全一致的,没有任何区别,都相当于执行了一个中断响应的过程,因为系统调用实际上最终是中断机制实现的,而异常和中断的处理机制基本上也是一致的,关于它们的具体区别这里不再赘述。关于中断处理机制的细节和步骤这里也不做过多分析,涉及到由用户态切换到内核态的步骤主要包括: [1]从当前进程的描述符中提取其内核栈的ss0及esp0信息。 [2]使用ss0和esp0指向的内核栈将当前进程的cs,eip,eflags,ss,esp信息保存起来,这个 过程也完成了由用户栈到内核栈的切换过程,同时保存了被暂停执行的程序的下一 条指令。 [3]将先前由中断向量检索得到的中断处理程序的cs,eip信息装入相应的寄存器,开始 执行中断处理程序,这时就转到了内核态的程序执行了。 发信人:djq(the Dark),信区:Linux 标题:UNIX高级教程系统技术内幕第二章(2) 发信站:BBS水木清华站(Sat Feb 10 15:54:52 2001) ?信号处理程序及相关信息(参考第4章)。 ?由程序头中获得的信息,如正文,数据,堆栈大小和其他内存管理信息。 ?打开文件描述符表(8.2.3节)。现代UNIX系统,如SVR4,可以按需动态地扩展这 张表。 ?指向当前目录的v节点和控制终端的指针。v节点代表文件系统对象,8.7节中进一 步讨论。 ?CPU使用统计,概况统计信息,磁盘限量和资源限制信息。 ?许多实现中,每个进程的内核堆栈是u区的一部分。 proc结构中的主要域如下: ?标识:每个进程有一个唯一的进程ID(PID)井属于一个特定的进程组。较新的版本 还分配给每个进程一个会话ID。 ?当前进程中u区的内核地址映射表位置。 ?当前进程状态。 ?在调度队列,阻塞队列或睡眠队列中的向前指针和向后指针。 ?阻塞进程的睡眠通道(7.2.3节)。 第5章)。 ?调度优先级和相关信息( ?信号处理信息:各种信号,包括忽略信号、阻塞信号、已发送信号及已处理信号 的掩码(第4章)。 ?内存管理信息。 ?将这个结构链接到活动进程,空闲进程或僵尸进程队列的指针。 ?各种标志。 ?将结构链接到基于PID的哈希队列(hash queue)中的指针。 ?层次信息,描述进程与其他进程间的关系。 图2-4给出了4.3BSD UNIX中的进程关系。描述这种关系的域是p_pid(进程ID),p_ ppid(父进程ID),p_pptr(指向父进程的proc结构),p_cptr(指向最大的子进程),p_ys ptr(指向下一个更小的兄弟进程)和p_osptr(指向下一个的更大兄弟进程)。 许多现代UNIX变体已经改变了这种进程抽象,在一个单一进程中支持几个线程。我 们将在第3章中详细讨论。 2.4内核态下运行 有三件事件会导致系统进人内核态--设备中断,异常,自陷或软中断。在每一种 情况下,当内核接收到控制权,它依赖于派遣表控制转移方向。派遣表中包括处理这些 事件的底层例程的地址。在调用相应的例程前,内核在内核栈上保存被中断进程的某种 状态(如它的程序计数器,处理器状态字)。当例程完成后,内核恢复进程的状态,并将 执行模式恢复为原来的模式(在内核态发生中断时,中断处理程序完成后仍返回内核态) 。 这里有必要区分中断和异常。中断是由外围设备,如磁盘,终端或硬时钟引起的异 步事件。由于中断不是当前正在运行的进程引起的,它们必须在系统上下文中被处理, 而不可以 图2-4 4.3BSD UNIX中典型的进程层次 访问进程地址空间和u区。同理,它们也不能被阻塞,否则会阻塞其他进程。异常对进程 而言是同步的,是由进程自身相关的事件引发的,如除0或访问非法地址。因此异常处理 程序应在进程上下文中运行,它可访问进程的地址空间和u区,必要时可以被阻塞。软件 中断或自陷,在系统执行特殊指令时出现,如有系统调用,在进程上下文中同步处理。 2.4.1系统调用接口 系统调用的集合定义了内核向用户进程提供的编程接口。缺省链接到所有用户程序 的C语言库为每个系统调用设置了一个包装例程。当用户程序调用一个系统调用时, 就会调用相应的包装例程。这个例程将系统调用号(它标识内核的特定系统调用)压入用 户栈,然后调用特殊的trap指令。这个指令的实际名字是与机器相关的(例如,MIPS R 3000d的syscall,VAX-ll的chmk或Motorola 680x0的trap)。这条指令的功能是 将执行模式变为内核态.井将控制权转移到定义派遣表中的系统调用处理程序。这个一般 称为syscall()的处理程序是内核中所有系统调用过程的起点。 系统调用在内核态中执行,但却是进程上下文。因此它可以访问进程地址空间和u区 。由于它运行于内核态,它使用调用进程的内核栈。syscall()将系统调用参数从用户栈 拷贝到u区,并在内核栈上保存硬件上下文。然后它使用系统调用号作为系统调用派遣向 量(一般为sysent)的索引,确定内核函数应执行哪个特定的系统调用。当那个函数返 回后,syscall()在对应的寄存器中设置返回值或错误状态,恢复硬件上下文,返回用户 态,将控制权还给库例程。 2.4.2中断处理 机器上中断的主要功能是允许外围设备与CPU交互,通知CPU任务完成,错误状态 或其他急需注意的事件。这些中断的产生与正常系统活动是异步的(如系统不知道在指令 流的哪一处会发生中断),并且一般与任何特定进程无关。被调用处理中断的函数称为中 断处理程序或中断服务例程。处理程序运行在内核态并处于系统上下文中。由于被中断 的进程一般与中断没有关系,处理程序应注意不要访问进程上下文。由于同样的原因, 中断处理程序不允许被阻塞。 然而对中断进程还是有一些影响。尽管中断与进程无关,中断服务所使用的时间被 计入进程的时间片中。同时,时钟中断处理程序计算当前进程的时标(两个时钟中断之间 的时间)。因此需访问当前进程的proc结构。有一点非常值得注意,即进程上下文并未明 确受到保护以防止中断处理程序对其进行访问。一个不正确的处理程序有可能破坏进程 地址空间的任何部分。 内核也支持所谓的软中断或自陷,它们是由执行特殊的指令触发的。这些中断用来 完成诸如触发上下文切换或调度低优先级的时间相关任务。尽管这些中断同一般系统活 动同步,它们的处理同一般中断相似。 由干有不同的事件可能引发中断,所以一个中断可能在另一个中断被服务时发生。 UNIX系统对这种需求的方法是,将中断区分为不同的中断优先级,允许高优先级的中断 可抢占低优先级的中断服务。例如硬件时钟中断必须高上网络中断,因为后者需要大量 数据,并跨越几个时标。 UNIX系统给每一种类型的中断一个中断优先级(interrupt priority level,ipl)。 早期UNIX实现的ipl范围从0~7。BSD将其扩展为0-31。处理器状态寄存器(proces sor status register)一般保存当前(或前面)?的位域。正常内核与用户进程运行于基 本冲ipl上。中断优先级的号码不仅在不同的UNIX变体上有所不同,而且在不同的硬件体 系结构上也不相同。某些系统中,ipl0是最低优先级,而在其他系统中都是最高的。为 了给内核和设备驱动程序开发者以便利,UNIX系统提供了一组阻塞和非阻塞中断的宏。 但不同的UNIX变体使用不同的宏达到相同的目的。表2-1中列举了一些在4.3BSD和SVR4 中使用的宏。 表2-1 4.3BSD和SVR4中设置中断优先级的操作 ?某些处理器,加Intel 80x86,不能从硬件上支持中断优先级。在这种系统中,照作 系统必须用软件来实现ipl。练习里更详细地讨论了这个问题。 当中断发生时,如果它的优先级高于当前的中断优先级,当前处理就被挂起,并调 用新中断处理程序。中断处理程序在新的ipl上开始执行。当处理程序结束时,ipl降低 为上一个值(这通过保存在中断栈上的旧的处理器状态字取得),内核恢复被中断的进程 。内核收到中断的ipl低于或等于当前中断ipl,这个中断并不立即处理,而是存储在中 断寄存器中。当你降到足够低时,这个保存的中断再重新被处理。这一过程如图25所述 。 图2-5中断处理 ipl的比较及硬件设置都是以机器相关方式处理的。UNIX也为内核显式地提供一种检 查和设置ipl的机制。例如内核在处理某些临界区代码时,可以升高ipl以阻塞中断。这 些将 在2.5.2节中有深入讨论。 某些机器为所有中断处理程序提供了一个单独的全局中断栈(interrupt stack)。在 没有中断栈的机器上,中断处理程序在当前进程的内核栈上运行。它们必须保证其余的 内核栈同这个处理程序隔绝。内核是通过在调用处理程序之前在内核栈上压入一个上下 文层(context layer)实现这一目的的。与栈结构相似,这个上下文层包含句柄返回时恢 复先前执行环境的信息。 2.5同步 UNIX内核是可重入的。任何时刻都可能会有若干进程同时在内核中活动。但它们中 只有一个(在单处理器中)是实际运行着的;其他进程被阻塞,等待CPU或其他资源。由于 它们共享内核数据结构的同一副本,为了防止内核崩溃,有必要加上某种形式的同步。 图2-6所示是一个没有同步情况下会发生的例子。假设一个进程希望从链表中删除元 素B。它执行了第一行代码,但在执行下一行代码之前被中断,这时另一个进程得以执行 。若第二个进程访问同一链表,它将发现该链表处于不一致状态,如图2-6(b)所示。显 然,我们应确保这些情况不会发生。 图2-6从链表中删除一个元素 UNIX使用几个同步技术。第一条防线是UNIX内核是不可抢占的。这意味着任何一个 在内核中执行的进程,尽管其时间片可能已用完,也不能被其他进程抢占。这个进程必 须是自愿放弃CPU。这种情况通常是进程在等待资源或事件被阻塞时,或是当它完成内核 态活动后准备返回用户态时发生。上述两种情况下,因为CPU是自愿放弃的,进程可确保 内核处于一个一致的状态。具有实时性的现代UNIX内核允许在一定条件的重入(在5.6节 有详细讨论)。 内核的非抢占特性为大多数同步问题提供全面而彻底的解决.如图2-6,当没心 抢占问题时,内核管理链表时就无需加锁。但有三种情况同步仍是必需的--阻塞操作, 中断和多处理器同步。 2.5.1阻塞操作 阻塞操作会阻塞进程(在操作完成时使进程处于asleep状态)。由于内核是非抢占的 ,它可以无忧无虑地管理大多数对象(数据结构和资源),没有其他进程会破坏它们。但 还有一些对象,在阻塞操作过程中必须受到保护,这就需要额外的机制。例如,进程开 始将数据从一个文件读取到内核内存区的磁盘缓冲区中。因为需要磁盘I/O,进行必须等 待I/O完成,同时允许其他进程运行。然而,由于缓冲区尚处于不一致状态,内核必须确 保其他进程不能以任何方式访问这个缓冲区。 为保护这种对象,内核为其关联一把锁。锁可以是一个简单的位标志,加锁时对其 进行置位,解锁时清位。任何进程在使用这个数据对象之前都必须检查其是否加锁。若 已加锁,它必须等待该对象被解锁。若未加锁,它就对对象加锁并开始使用。一般而言 ,内核同时为对象关联一个需求(wanted)标志。当进程需要该数据对象但发现其已被加 锁时,设置这个标志。当进程准备释放一个加锁对象时,它检查需求标志看是否其他进 程等待使用这个对象,若有则唤醒这些进程。这个机制允许进程在很长一段时间内锁住 资源,而在加锁期间该进程可以被阻塞并允许其他进程同时运行。 图2-7给出了对资源加锁的算法。以下几点需要注意: ?当一个进程不能获得资源或等待诸如I/O完成这类事件时,进程阻塞自己。这是通 过调用sleep()完成的,这称为阻塞于资源或事件。 ?sleep()将进程放在特殊的阻塞进程队列上,将其状态置为睡眠,并调用函数sw tch()开始上下文切换,允许其他进程执行。 ?进程释放资源后调用wakeup()唤醒等待这个资源的所有进程?。wakeup()找到每 一个这样的进程,将其状态变为可运行状态(runnable),井把它加入调度队列等待系统 调度。 ?一个进程从被唤醒到其被调度执行之间可能有一个很长的延时。其他进程可能会 在这期间运行,并可能会再次对同一资源加锁。 ?因此在被唤醒运行后,进程仍需对资源进行检查,看其是否确实可用,若不可用 则再次睡眠。 2.5.2中断 尽管内核不会被其他进程抢占,但一个正操作内核数据结构的进程却可被设备中断 。若这个中断处理程序正好也要访问那些数据结构,它们就可能会处于不一致状态。处 理这个问题的方法是在访问这些数据结构时屏蔽中断。内核使用诸如表2-1中的那些宏 显式地提高?近期的UNIX版本中若干wakeup()的替代函数,如wake_one()和wakepr ocs()。 ipl来屏蔽中断。这种代码段你为临界区(critical region)(见例2-1)。 实例2-1在临界区内屏蔽中断 int x=splbio();/*rases ipl,returns previos ipl*/ modify disk buffer cache; splx(x);/*restores previous ipl*/ 图2-7资源加锁算法 中断屏蔽时要注意以下几点: ?中断一般要求快速处理,不应受到严重干扰。因此,临界区应少而短。 ?只有那些可能访问临界区中数据的中断才必须屏蔽。在上面那个例子中,只有 磁盘中断需被屏蔽。 ?两个不同的中断可以有相同的优先级。例如,许多系统中终端和磁盘中断的中 断优先级都是21。 ?屏蔽一个中断会将所有相同优先级或更低优先级的中断屏蔽。 注意:在描述UNIX系统时(block)这个词有许多不同用法。当一个进程系统等待资 源可用或事件发生而进入睡眠称为进程阻塞于资源或事件。进程屏蔽(block)中断或信号 使其暂时不能传递。最后,I/O子系统与存储设备间按固定大小的块传输数据。 2.5.3多处理器 由于内核所具有的最基本保护方式非抢占特性不复存在,多处理器系统有一类新的 同步问题。在单处理器,由于不可抢占,内核可以毫无顾忌地处理大多数数据结构。它 只需保护那些中断处理程序要访问的数据结构,或是调用sleep()需要保持一致的数据 。 在多处理器中,两个进程会在不同处理器上同时处于内核态,甚至并发地执行同一 函数。因此,任一时刻当内核访问某一全程数据结构时,必须对其加锁以防其他处理器 访问。这种加锁机制必须是多处理器安全的。若有不同处理器上运行的两个进程同时希 望对某一对象加锁,只能有一个能成功地获取锁。 由于有多个处理器处理中断,对中断的保护更加复杂。通常阻塞每个处理器上的中 断不是很好的方法,因为这可能会极大地降低性能。显然多处理器需要更复杂的同步机 制。第7章详细分析这些问题。 2.6进程调度 CPU是一个由所有进程共享的资源。内核中在进程间分配CPU时间的那部分称为调度 器(scheduler)。传统UNIX调度器使用抢占式轮转调度、相同优先级的进程以轮转方式调 度,每个运行一个固定的时间片(通常是100毫秒)。若有一个更高优先级的进程准备 就绪,无论当前进程是否用完其时间片,它都会被那个高优先级进程抢占(除非当前进程 正在内核态运行)。 传统UNIX中系统,进程优先级由两个因素决定的-nice值和usage因子。用户通过n ice系统调用更改进程的nice值,影响进程的优先级(只有超级用户可以增加进程优先级 )。usage因子是对进程近期使用CPU的度量。它允许内核动态的改变进程优先级。当进程 不在运行时,内核定期增加它的优先级。当进程正在占用CPU时间时,内核减少其优先 级。由于就绪进程的优先级最终会升到足够高而被调度,这种策略会防止某些进程的饿 死现象。 在内核中运行的进程由于阻塞于资源或事件而放弃CPU。当它再次变为就绪后,它被 赋予内核优先级。内核优先级高于任何用户优先级。传统UNIX内核中,调度优先级的值 范围是0~127的整数,值越小,优先级越高。(由于UNIX系统绝大部分用C写成,它遵 循标准习惯从0开始计数)。例如,4.3BSD中内核优先级为0~49,用户优先级50~127。 用户优先级随CPU使用的不同而变化,而内核优先级是固定的,因睡眠原因而定。正因为 如此,内核优先级也称为睡眠优先级。表2-2是4.3BSD UNIX的睡眠优先级。 表2-2 4.3BSD UNIX中的睡眼优先级 特别声明: 1:资料来源于互联网,版权归属原作者 2:资料内容属于网络意见,与本账号立场无关 3:如有侵权,请告知,立即删除。
/
本文档为【内核栈 系统调用】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索