24Linux的进程管理.docx
- 文档编号:11221551
- 上传时间:2023-02-25
- 格式:DOCX
- 页数:9
- 大小:17.73KB
24Linux的进程管理.docx
《24Linux的进程管理.docx》由会员分享,可在线阅读,更多相关《24Linux的进程管理.docx(9页珍藏版)》请在冰豆网上搜索。
24Linux的进程管理
2.4Linux的进程管理
Linux中的每一个进程用一个task_struct数据结构来表示,所有指向这些数据结构的指针构成进程的向量数组task,系统的进程向量数组大小是512,系统中最多能容纳512个进程(Linux2.4及以后内核无此限制)。
当新的进程创建的时候,从系统内存中分配一个新的task_struct结构,并加到task数组中。
当前进程指针current指向当前运行的进程。
task_struct的结构描述在/include/linux/seched.h文件中。
2.4.1Linux的进程控制块task_struct及进程状态
1.Linux的进程控制块task_struct
在Linux中进程称为任务,进程控制块是task_struct结构,它在include/linux/sched.h中定义并解释。
structtask_struct{
/*thesearehardcoded-don'ttouch*/
volatilelongstate;/*-1unrunnable,0runnable,>0stopped*/
longcounter;
longpriority;
unsignedlongsignal;
unsignedlongblocked;/*bitmapofmaskedsignals*/
unsignedlongflags;/*perprocessflags,definedbelow*/
interrno;
longdebugreg[8];/*Hardwaredebuggingregisters*/
structexec_domain*exec_domain;
/*variousfields*/
structlinux_binfmt*binfmt;
structtask_struct*next_task,*prev_task;
structtask_struct*next_run,*prev_run;
unsignedlongsaved_kernel_stack;
unsignedlongkernel_stack_page;
intexit_code,exit_signal;
/*?
?
?
*/
unsignedlongpersonality;
intdumpable:
1;
intdid_exec:
1;
intpid;
intpgrp;
inttty_old_pgrp;
intsession;
/*booleanvalueforsessiongroupleader*/
intleader;
intgroups[NGROUPS];
/*
*pointersto(original)parentprocess,youngestchild,youngersibling,
*oldersibling,respectively.(p->fathercanbereplacedwith
LinuxKernelPage147
*p->p_pptr->pid)
*/
structtask_struct*p_opptr,*p_pptr,*p_cptr,
*p_ysptr,*p_osptr;
structwait_queue*wait_chldexit;
unsignedshortuid,euid,suid,fsuid;
unsignedshortgid,egid,sgid,fsgid;
unsignedlongtimeout,policy,rt_priority;
unsignedlongit_real_value,it_prof_value,it_virt_value;
unsignedlongit_real_incr,it_prof_incr,it_virt_incr;
structtimer_listreal_timer;
longutime,stime,cutime,cstime,start_time;
/*mmfaultandswapinfo:
thiscanarguablybeseenaseither
mm-specificorthread-specific*/
unsignedlongmin_flt,maj_flt,nswap,cmin_flt,cmaj_flt,cnswap;
intswappable:
1;
unsignedlongswap_address;
unsignedlongold_maj_flt;/*oldvalueofmaj_flt*/
unsignedlongdec_flt;/*pagefaultcountofthelasttime*/
unsignedlongswap_cnt;/*numberofpagestoswaponnextpass*/
/*limits*/
structrlimitrlim[RLIM_NLIMITS];
unsignedshortused_math;
charcomm[16];
/*filesysteminfo*/
intlink_count;
structtty_struct*tty;/*NULLifnotty*/
/*ipcstuff*/
structsem_undo*semundo;
structsem_queue*semsleeping;
/*ldtforthistask-usedbyWine.IfNULL,default_ldtisused*/
structdesc_struct*ldt;
/*tssforthistask*/
structthread_structtss;
/*filesysteminformation*/
structfs_struct*fs;
/*openfileinformation*/
structfiles_struct*files;
/*memorymanagementinfo*/
structmm_struct*mm;
/*signalhandlers*/
structsignal_struct*sig;
#ifdef__SMP__
intprocessor;
LinuxKernelPage148
intlast_processor;
intlock_depth;/*Lockdepth.
Wecancontextswitchinandout
ofholdingasyscallkernellock...*/
#endif
};
2.Linux中的进程状态及其转换
Linux中进程有6种状态,分别是:
1)可运行状态(TASK_RUNNING),正在运行或准备运行的进程处
于这种状态。
2)可中断阻塞状态(TASK_INTERRUPTIBLE),处于这种阻塞状
态中的进程,只要阻塞的原因解除,就可以被唤醒到就绪队列,也可以由其他进程通过信号或定时中断唤醒。
3)不可中断阻塞状态(TASK_UNINTERRUPTIBLE),处于这种阻塞状态的进程,只能在资源请求得到满足时唤醒到就绪队列,不能通过信号或定时中断唤醒。
4)僵死状态(TASK_ZOMBIE),处于这种状态的进程已经结束运行,离开CPU,并归还所占用的资源,只是进程控制块PCB结构还没有归还释放。
5)暂停状态(TASK_STOPPED),处于这种状态的进程被暂停执行而阻塞,通过其他进程的信号才能唤醒。
6)交换状态(TASK_SWAPPING),处于这种状态时,进程的页面可以从内存换出。
2.4.2Linux的进程控制
进程控制主要包括进程的创建、执行、撤消、等待和结束等。
这些系统调用是进程编程中最常用和基本的函数。
1.进程的创建fork
1)fork系统调用
在Linux中,一个已有的进程只有通过fork()系统调用才能创建一个新的进程,其描述为:
intfork()
正确返回:
0:
从子进程返回
>0:
从父进程返回,返回值为子进程的进程标识号
错误返回:
-1
一个成功的fork调用将使内核创建一个新的进程,该进程是调用进程的一个精确的副本。
也即新的进程运行了创建者进程的一个副本。
printf(“One\n”);←PC
pid=fork();
printf(“Two\n”);
A进程之前
---------------------------------------------------------------------------------
之后
printf(“One\n”);printf(“One\n”);
pid=fork();pid=fork();
printf(“Two\n”);←PCprintf(“Two\n”);←PC
A进程B进程
fork之后部分内的两处PC箭头,表示在fork调用之后父子进程均执行的下一条语句。
也即A和B都处于程序代码的同一点上。
下面是一个简单的父进程创建子进程的例子:
#include
#include
#include
main()
{
pid_tpid;
pid=fork();
if(pid<0)
{
printf(“forkerror\n”);
exit(0);
}
elseif(pid==0)
{
printf(“Thisischildprocess!
\n”);
}else{
printf(“Thisisparentprocess!
\n”);
}
exit(0)
}
在fork()中,调用do-fork()函数来完成进程的创建(见kernel/fork.c),子进程被创建后,进入就绪队列和父进程分别独立地等待调度。
子进程继承父进程的程序代码,子进程被调度执行时,和父进程一样从fork返回。
从fork返回后,都执行pid=fork()语句,得到返回的值,pid的值有三种可能性:
A.小于0,表示fork出错;
B.等于0,表示当前进程是子进程;
C.大于0,表示当前进程是父进程。
从进程调度的角度来看,子进程被父进程创建后处于就绪态,此时,父进程和子进程作为二个独立的进程,共享同一个代码段,分别参加调度、执行,直到进程结束,但是谁先得到调度,与系统的调度策略和系统当前的资源状态有关,是不确定的。
因此,谁先从fork函数中返回继续执行后面的语句也是不确定的。
2)vfork调用
vfork函数用于创建子进程,其调用方法和返回值与fork函数相同,但处理子进程与父进程的关系上有所不同,子进程创建后,先于父进程运行。
3)实例
调用fork创建一个子进程,改变在父进程创建子进程之前定义的变量的值,观察该变量在子进程和父进程中的值。
#include
#include
#include
main()
{
pid_tpid;
intdata=5;
if((pid=fork())<0)
{
printf(“forkerror\n”);
exit(0);
}
elseif(pid==0)
{
data--;
printf(“child’sdatais:
%d\n”,data);
exit(0);
}
else
{
printf(“parent’sdatais:
%d\n”,data);
}
exit(0);
}
2.进程的执行exec
在应用中,常需要在一个程序中启动另一个应用程序,在Linux中用函数exec()实现这样的功能。
#include
intexecv(constchar*file,char**argv,char**envp)
正确返回:
0
错误返回:
-1
当一个进程调用exec函数执行另一个程序后,这个进程被新程序取代,包括代码段、数据段、堆栈段等,同时继承原进程的进程标识号。
execv()函数调用do-execve()函数,实现一个新程序的启动,代码详见/src/linux/fs/exec.c。
例:
在程序中直接调用execv启动shell命令ps查看系统当前的进程信息。
#include
#include
#include
main()
{
intret;
char*path=”/bin/ps”;
char*argv[5]={“ps”,”-a”,”-x”,NULL};
if(execv(path,argv))
{
syslog(LOG_INFO,”Errorexecutingaprogram”);
}
return(0);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 24 Linux的进程管理 Linux 进程 管理