用户级进程和内核进程 用户进程的区别和联系

温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
2、当程序被操作系统加载到内存并分配它一定资源后,此时可称为进程 3、为方便操作系统管理,每个进程都会有一个唯一的非负整数编号 4、程序是一个静态的概念,进程是一个动态的概念进程的内存空间:内核1G,用户3G linux的虚拟地址空间为0-4G,分为用户空间和内核空间两部分。操作系统把最高的1G,即从0xCxFFFFFFFF划分给内核使用,称为内核空间。将较低的3G字节,从0xxBFFFFFFF,供各个进程使用,称为用户空间。每个进程可以通过系统调用进入内核,因此从具体进程的角度看,每个进程都拥有4G的虚拟空间。当进程陷入内核时,内核代表进程运行。进程的状态: 1、用户状态:进程在用户状态下运行 2、内核状态:进程在内核状态下运行 3、内存中就绪:进程没有执行,但是处于就绪状态,只要内核调度它,就可以执行 4、内存中睡眠:进程正在睡眠并且进程存储在内存中,没有被交换到SWAP设备。 5、就绪且换出:进程处于就绪状态,但是必须把它换入内存,内核才能再次调度它进行运行 6、睡眠且换出:进程正在睡眠,且被换出内存 7、被抢先:进程从内核状态返回用户状态时。内核抢先于它,做了上下文切换,调度了另一个进程,原先这个进程就处于被抢先状态。 8、创建状态:进程刚刚被创建。该进程存在,但是既不是就绪状态,也不是睡眠状态,这个状态时除了进程0以外的所有进程的最初状态。 9、僵死状态:进程调用exit结束,进程不再存在,但在进程表项中仍有记录,该记录可由父进程收集。 图:进程状态和转换关系 & &10、用户级线程拥有的几种状态和对应宏值
#define &&TASK_RUNNING & 0;//正在运行或处于就绪状态
#define & TASK_INTERRUPTIBLE & 1;//处于等待队伍中,等待资源有效时唤醒,并可以被中断
#define & TASK_UNINTERRUPTIBLE & &2;//处于等待队伍中,等待资源有效时唤醒,但不可被中断
#define & TASK_ZOMBIE & 4;//即将从任务链表中删除,但在TASK中仍然有task_struct数据,等待父进程释放。
#define & TASK_STOPPED & 8;//进程已经结束,已经释放了相应的资源,但未释放进程控制块PCB,因此处于该状态的进程还是可以被唤醒。 11、内核进程的几种状态及对应的宏值
#define & TASK_RUNNING & & 0;
#define & TASK_INTERRUPTIBLE & &1;
#define & TASK_UNINTERRUPTIBLE & &2;
#define & TASK_STOPPED & & 4;
#define & TASK_TRACED & & &8;
#define & EXIT_ZOMBIE & & &16;
#define & EXIT_DEAD & & 32; 12、Linux 系统中当前的所有任务都在以上状态中不断的切换。至于什么时候由哪一个进程占有CPU,则由linux的调度程序决定,调度程序所依据的算法称为调度算法。进程的基本属性:进程号(PID)、父进程号(PPID)、进程组号(PGID) 1、进程号(PID):进程号是系统维护的唯一标识一个进程的正整数。进程号是无法在用户层修改的。在Linux系统中,系统的第一个用户进程是init进程,它的进程号为1,其他进程的进程号依次增加。用户可以通过 “ps aux”命令查看当前系统所有进程的基本属性。 2、获取进程PID:getpid()
1】头文件:#include &&unistd.h&
2】函数原型:extern &__pid_t & getpid(void);
3】返回:如果执行成功,则返回当前进程的pid &类型为pid_t ,如果执行失败则返回-1,错误原因存储在errno中。pid_t &其实就是 int 型,重新定义可提高代码的可读性。 3、获取父进程号PPID:getppid() &
任何进程(除init进程)都由另一个进程创建,该进程称为被创建进程的父进程,被创建的进程称为子进程。父进程的进程号无法在用户层修改。父进程的进程号PID,即为子进程的父进程号PPID,用户可以通过getppid函数来获得当前进程的父进程号(PPID)。
1】头文件:#include &&unistd.h&
2】函数原型:extern &__pid_t& &getppid(void);
3】返回值:如果执行成功,返回父进程的PID,类型为pid_t,如果执行失败则返回-1; 4、获得进程组号PGID:getpgid()
进程组是一个或多个进程的集合。它们与同一作业相关联,可以接受来自同一终端的任何信号。每个进程组都有唯一的进程组号,进程组号可以在用户层修改。
每个进程组都可以有一个组长进程,组长进程的进程号为该组的进程组号。组长进程可以先退出,只要在进程组中有一个进程存在,该进程组就存在,与组长进程时候退出无关。进程组的最后一个进程可以终止,或者转移到另一个进程组。
1】头文件:#include &&unistd.h&
2】函数原型:extern &__pid_t& &getpgid(
__pid_t& &__pid);
3】参数说明:传入参数为要获得进程组号的进程号。如果为0,表示获取当前进程的进程组号
4】返回:执行成功返回当前进程的进程组号,执行失败返回-1,错误原因存在errno中。
5】备注:getpgrp()也可以用来获取进程组号 pid_t &getpgrp(void); 5、修改进程组号:setpgid()&
1】函数原型:int &setpgid(pid_t &pid &,pid_t &pgid);
2】参数说明:(1)pid为欲修改进程PGID的进程PID,pgid为新的进程组号。如果这两个参数相等,则由pid指定的进程变成进程组的组长;如果pid为0,则修改为当前进程的PGID,如果pgid为0,则由pid指定的进程的PID将作为进程组号的PGID。(2)一个进程只能为自己或子进程设置进程组号PGID,在它的子进程调用了exec函数后,就不能改变该子进程的进程组号了。(3)在大多数作业控制的shell中,首先使父进程为新的进程组的组长,在创建子进程后,再把子进程设定为进程组的组长,以免造成组员身份的不确定。 6、获取进程的会话号SID:getsid()
1】函数原型:extern __pid_t& getsid(__pid_t& &__pid);
2】返回:如果pid为0,返回调用进程的会话号SID,一般来说,该值等于进程组号PGID。如果pid并不属于调用者所在的会话,则调用者就不能得到。 7、创建新会话:setsid()
1】函数原型:extern &__pid_t &setsid(void);
(1)如果调用进程已经是一个进程组的组长,则此函数返回出错。为避免这种情况,通常先调用fork创建子进程,然后使其父进程终止,而子进程则继续,在子进程中调用该函数。
(2)如果调用函数的进程不是一个进程组的组长,则此函数会创建一个新的会话:
A、该进程变成新会话首进程,会话的首进程是创建该会话的进程。
B、该进程称为一个新进程组的组长进程。新进程组的PGID就是该调用进程的PID
C、该进程没有控制终端,如果调用setsid之前,该进程就有一个控制终端,那么这种联系也会被中断。 8、控制终端:会话和进程组的特点:
A、一个会话可以有一个控制终端,建立与终端连接的会话首进程被称为控制进程
B、一个会话中的几个进程组可被分为一个前台进程组和几个后台进程组,如果一个会话有一个控制终端,则它有一个控制终端。
C、无论何时键入终端的中断键(DELETE或CTRL+C),都会将中断信号发送给前台进程组的所有进程;无论何时键入终端的退出键(ctrl + \),都会把退出信号发送到前台进程组的所有进程。如果终端检测到调制解调器(或网络)已经断开连接,则将挂断信号发送给控制进程(会话首进程)。 9、获取当前前台进程组的进程号:tcgetpgrp()
1】函数原型:pid_t &tcgetpgrp(int filedes);
2】返回:返回与打开的终端(由filedes指定,用open打开设备终端时返回的文件描述符)相关联的前台进程组的进程组号。 10、设置某个进程组是前台进程组还是后台进程组:tcsetpgrp()
1】函数原型:pid_t &tcsetpgrp(int filedes,pid_t &pgrpid);
2】如果进程有一个控制终端,则将前台进程组的ID设置为pgrpid,pgrpid的值应该在同一会话中的一个进程组ID,filedes为一个文件描述符。进程的用户属性:RUID、EUID、GID、EGID Linux对权限有严格控制,某个进程有真实的用户号(RUID)、真实的用户组号(RGID)、有效用户号(EUID),有效用户组号(EGID) 1、获取进程真实用户号RUID:getuid()
1】头文件:#include &&unistd.h&
2】函数原型:extern &__uid_t &getuid(void);
3】返回:此函数执行成功,则返回当前进程的UID,执行失败则返回-1,错误原因保存在errno中。
4】说明:对于进程而言,创建该进程的用户UID(执行此程序的用户)为此进程真实用户号(RUID)。 2、获取进程有效用户号EUID:geteuid()
1】说明:EUID主要用于权限检查。多数情况下,EUID和UID相同。如果可执行文件的setuid位有效,那么该文件的拥有者之外的用户运行该程序时,EUID和UID不相同;即当某可执行文件设置了setgid位后,任何用户(包括root用户)运行此程序时,其有效用户组EUID为该文件的拥有者。
2】头文件:#include & &unistd.h&
3】函数原型:extern &_uid_t & &geteuid (void)
4】返回:执行成功返回当前进程的EUID,执行失败返回-1,错误原因存储在errno中。 3、获取进程的用户组号:getgid()
1】函数说明:创建进程的用户所在的组号为进程的进程用户组号(GID)。可以通过调用getgid()来获得当前进程真实的用户组号(GID)。
2】头文件:#include & &unistd.h&
3】函数原型:extern &_uid_t & getgid(void)
4】返回:如果执行成功将返回当前进程的GID,执行失败则返回-1,错误原因存储在errno中 4、获取当前进程有效的用户组号:getegid()
1】函数说明:与EUID相似,某文件设置了setgid位,那么任何用户(包括root用户)运行此程序时,其有效的EGID为该文件的拥有者所在的组。
2】头文件:#include & &unistd.h&
3】函数原型:extern &_uid_t & getegid(void)
4】函数原型:执行成功返回当前进程的EGID,执行失败返回-1,错误原因存放在errno中。
阅读(190)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'LINUX高级编程基础系列:进程和进程属性',
blogAbstract:'进程和程序的关系:\t1、程序是一个包含可执行代码的文件,它放在磁盘等介质上。\t2、当程序被操作系统加载到内存并分配它一定资源后,此时可称为进程\t3、为方便操作系统管理,每个进程都会有一个唯一的非负整数编号\t4、程序是一个静态的概念,进程是一个动态的概念进程的内存空间:内核1G,用户3G\tlinux的虚拟地址空间为0-4G,分为用户空间和内核空间两部分。操作系统把最高的1G,即从0xCxFFFFFFFF划分给内核使用,称为内核空间。将较低的3G字节,从0xxBFFFFFFF,供各个进程使用,称为用户空间。每个进程可以通过系统调用进入内核,因此从具体进程的角度看,每个进程都拥有4G的虚拟空间。当进程陷入内核时,内核代表进程运行。',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}2011年12月 硬件/嵌入开发大版内专家分月排行榜第三2011年10月 硬件/嵌入开发大版内专家分月排行榜第三2011年6月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。【图文】操作系统第一章答案_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
操作系统第一章答案
上传于|0|0|文档简介
&&操作系统 吴小平 罗俊松 机械工业出版社
大小:500.50KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢“用户级线程”和“内核级线程”
线程的实现可以分为两类:用户级线程(User-Level Thread)和内核线线程(Kernel-Level Thread).后者又称为内核支持的线程或轻量级进程.用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。&内核线程: &&由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。Windows &&NT和2000/XP支持内核线程 &&&&&&&&&用户线程:由应用进程利用线程库创建和管理,不以来于操作系统核心。不需要用户态/核心态切换,速度快。操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少。Windows NT和OS/2支持内核线程。Linux&支持内核级的多线程-----------------------关于内核线程(kernel_thread)&唐宇 carino@mail.我们知道Linux内核使用内核线程来将内核分成几个功能模块,像kswapd,kflushd等,系统中的init进程也是由idle进程调用kernel_thread()来实现产生的.我们先来看看内核线程的实现,再来分析内核线程的性质.int kernel_thread(int(*fn)(void*arg),void *arg,int flags){long retval,d0;__asm__ __volitate__("movl %%esp,%%esi\n\t""int $0x80\n\t""cmpl %%esp,%%esi\n\t""je 1f \n\t""movl %4,%%eax\n\t""pushl %%eax\n\t""call *%5\n\t""movl %3,%0\n\t""int $0x80\n\t""1:\t":"=&a"(retval),"=&S"(d0):"0"(__NR_clone),"i"(__NR_exit),"r"(arg),"r"(fn),"b"(flags | CLONE_VM):"memory");}这段代码翻译成直观的ASM码:{movl __NR_clone,%0;movl __NR_exit,%3;movl arg,%4;movl fn,%5;movl flags|CLONE_VM,%mov %%esp,%%int $0x80;cmpl %%esp,%%je 1f;movl %4,%%pushl %%eaxcall *%5;movl %3,%0;int $0x80;1: movl %%eax,retvalmovl %%esi,d0}它的伪C码为:int kernel_thread(){pid=clone(flags);if(child){fn(arg);exit(0);}}从上面的代码可以看出,内核线程有以下性质:1.内核线程是通过系统调用clone()来实现的,使用CLONE_VM标志(用户还可以提供其他标志,CLONE_PID,CLONE_FS,CLONE_FILES等),因此内核线程与调用的进程(current)具有相同的进程空间.2.由于调用进程是在内核里调用kernel_thread(),因此当系统调用返回时,子进程也处于内核态中,而子进程随后调用fn,当fn退出时,子进程调用exit()退出,所以子进程是在内核态运行的.3.由于内核线程是在内核态运行的,因此内核线程可以访问内核中数据,调用内核函数.运行过程中不能被抢占等等.请注意在kernel_thread是如何调用系统调用的,我们知道kernel_thread是在内核中调用,所以他是可以直接调用系统调用的,像sys_open()等,但是在这里kernel_thread通过系统调用门(int$80)来间接调用clone()函数,就提出以下问题:1.为什么这样?2.如果我们直接调用sys_clone()会有什么样的结果呢?int kernel_thread(){pid=sys_clone();if(!pid){exit();}}这样,当子进程获取CPU资源时(运行时),从ret_from_fork恢复执行,栈布局对于子进程而言是不对的,问题在于当子进程运行到RESTORE_ALL的IRET,仔细想一想栈布局的变化.由sys_clone()的申明可知调用sys_clone需要pt_regs的栈结构,如果我们直接调用sys_clone是没用办法做到的(如果可以我们也需要精心为它准备栈,//:-(,真是伤神)同理,其他的类似系统调用,我们也必须通过int$80的系统调用门来实现.而对于sys_execl,sys_open,sys_close,sys_exit,则可以直接调用.//xixi,我们可以改动kernel_thread来测试sys_exit是否可以直接调用,同时也可以使用sys_clone的直接调用来证明我们的分析是否正确.而如果我们使用系统调用门(int$80)来解决问题,我们使用同样的方法来分析:A2)ebx &-- ( esp after save all ,ready for syscalls )ecx...oldeip &-- ( esp before SAVE_ALL which construct stack for syscalls )oldcseflagsd0 &- ( space for local variables )retvalfn &- ( arguments for kernel_thread )argclone_flagseip &- ( retore ip for kernel_thread )..由于kernel_thread在内核的代码段中,所以没有发生栈切换,所有的压栈/退栈都是在内核栈中进行的.请注意这样栈中便没有(OLDSS,OLDESP),所以在kernel_thread声明了两个局部参数(retval,d0),对于retval的意义是明显的,而d0大概是(dummy localvariable0,...n)的意思吧,:)B2)子进程运行前:子进程的TSS,栈布局ebx &- especx...oldeipoldcseflagsd0 &- (局部变量d0)retval &- (局部变量retval)运行到RESTORE_ALL时,将恢复CPU各寄存器,当运行到IRET时,由于在相同特权等级的转移,所以没有发生特权级切换,所以ESP,SS没有发生变化.BTW,由上面的分析可知,kernel_thread创建的进程是不能转到用户态运行的.-------------------------------&&Linux 为内核代码和数据结构预留了几个页框。这些页永远不会&被转出到磁盘上。从 0x0 到 0xc0000000 (PAGE_OFFSET) 的线性地址可由用户代码和内核代码进行引用。从 PAGE_OFFSET 到 0xffffffff 的线性地址只能由内核代码进行访问。这意味着在 4 GB 的内存空间中,只有 3 GB 可以用于用户应用程序。&我已经向您展示了(32 位架构上的) Linux 内核按照 3:1 的比率来划分虚拟内存:3 GB 的虚拟内存用于用户空间,1 GB 的内存用于内核空间。内核代码及其数据结构都必须位于这 1 GB 的地址空间中,但是对于此地址空间而言,更大的消费者是物理地址的虚拟映射。&某一个进程只能运行在用户方式(user mode)或内核方式(kernel mode)下。用户程序运行在用户方式下,而系统调用运行在内核方式下。在这两种方式下所用的堆栈不一样:用户方式下用的是一般的堆栈,而内核方式下用的是固定大小的堆栈(一般为一个内存页的大小)&所有的进程部分运行与用户态,部分运行于系统态。底层的硬件如何支持这些状态各不相同但是通常有一个安全机制从用户态转入系统态并转回来。用户态比系统态的权限低了很多。每一次进程执行一个系统调用,它都从用户态切换到系统态并继续执行。这时让核心执行这个进程。&在fork一个进程的时候,必须建立进程自己的内核页目录项(内核页目录项要与用户空间的的页目录放在同一个物理地址连续的页面上,所以不能共享,但所有进程的内核页表与进程0共享两个代表 (code 和 data/stack)是内核空间从[0xC000 0000] (3 GB)到[0xFFFF FFFF] (4 GB)&//线形地址两个代表 (code 和 data/stack)是用户空间从[0] (0 GB) 到 [0xBFFF FFFF] (3 GB)&&&&&&&&&//线性地址通常情况下,内核是不会调用用户层的代码,要想实现这逆向的转移,一般做法是在用户进程的核心栈(tss-&esp0)压入用户态的SS,ESP,EFLAGS,CS,EIP,伪装成用户进程是通过陷阱门进入核心态,之后通过iret返回用户态。在 32 位线形地址中的 4 GB 虚拟空间中,其中有 1 GB 作为 内核空间,从 3G—4G。 每个进程都有自己的 3 G 用户空间,它们共享1GB 的内核空间。当一个进程从用户空间进入内核空间时,它就不再有自己的进程空间了。应用程序在虚拟内存中布局,并且有一块很大的栈空间。当然是用来保存函数调用历史及当前函数中的自动变量的。而相反,内核具有非常小的栈,它可以只和一个 4096 字节的页那样大。我们自己的函数(如 LKM)必须和整个内存空间调用链一同共享这个栈。因此,声明大的自动变量并不是个好注意,若我们要大的结构,则应该在调用时动态分配。对内核线程的虚拟空间总结一下:1、创建的时候:父进程是用户进程,则mm和active_mm均共享父进程的,然后内核线程一般调用daemonize适头舖m父进程是内核线程,则mm和active_mm均为NULL总之,内核线程的mm = NULL;进程调度的时候以此为依据判断是用户进程还是内核线程。2、进程调度的时候如果切换进来的是内核线程,则置active_mm为切换出去的进程的active_mm;如果切换出去的是内核线程,则置active_mm为NULL。linux在创建用户任务的时候,给每个任务都分配了一个kernel mode stack。一个运行在用户态的任务如果被一个IRQ打断,中断处理要做一次堆栈切换。这时linux好像使用了任务的kernel mode stack,也就是说linux系统中没有一个唯一的系统堆栈,而是每一个任务都有一个系统堆栈,中断处理的栈使用的就是被打断任务的系统堆栈。内核线程也是进程,只不过没有自己的用户空间,但task_struct和内核堆栈还是得有的,要不怎么运行呢?[1.内核在主动进行进程调度时,可以自己设置将要投入运行进程的sp0为TSS段中的sp0,则该用户进程在进入内核后使用的是它自身的系统堆栈,但如果cpu运行在某一用户进程时,而为另一用户进程服务的外部中断发生了,在进入内核后使用的是当前用户进程的系统堆栈,还是中断服务的另一用户进程的系统堆栈呢?2操作系统映象是否拥有自己的堆栈空间?还是利用用户进程的系统堆栈?回答:&&1。外部中断不是为某个用户进程服务的,是为整个操作系统服务的,它始终用当前进程的核心堆栈。&2。用用户进程的系统堆栈。]&.&Kernel&Thread&与&LWP的关系首先线程和进程的概念(教科书中)是不同的,但是严格实现的角度来说去实现线程又不太现实。所以从实现线程一开始工程人员就是拿简化的进程(叫轻量进程)来模拟的线程,这涉及到进程所拥有的资源:内核部分:一个进程应该拥有个PCB块+7k的内核栈(严格来说比7k稍微小点点),还包括信号栈等等资源,都在那个8k的两个页面里面。核外部分:包含理论上4G的虚拟内存空间。在实现内核线程的时候,部分书籍上认为没有核外部分资源的“进程”就叫内核线程了。而普通的线程是通过共享核外部分的虚存来做的(实现的时候就是走的不同接口copy指针即可)。2.&Kernel&Thread&是怎样实现的&?&不是简单的说几个函数部分参考第1个问题的回答。创建内核线程的接口,应该是copy了对应的8k的两个页面,然后做了初始化,而核外的资源并没有获得到。3.&Unix&怎样调度这些&Kernel&Thread?有了上述的概念就比较清楚了,内核在调度的时候认的是PCB控制块,所以调度上是一样的。只是对于专门的kernel&thread,实现的时候做了些手脚,让其每隔一小段间隔来运行,做些清理、刷新、统计类工作。如有个回写磁盘的内核线程就是个非常典型的例子。
TA的推荐TA的最新馆藏[转]&用户级进程与内核进程_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
用户级进程与内核进程
上传于|0|0|文档简介
&&用户级进程与内核进程
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩1页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 内核进程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信