论坛风格切换
 
  • 帖子
  • 日志
  • 用户
  • 版块
  • 群组
帖子
购买邀请后未收到邀请联系sdbeta@qq.com
  • 1379阅读
  • 0回复

[求助-系统问题]电脑小知识 进程的基本概念 [复制链接]

上一主题 下一主题
离线凡一
 
发帖
*
今日发帖
最后登录
1970-01-01
只看楼主 倒序阅读 使用道具 楼主  发表于: 2009-05-28 19:14:35
1、进程的概念:进程是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源,比如说CPU(寄存器),IO,内存,网络资源等。很多人在回答进程的概念的时候,往往只会说它是一个运行的实体,而会忽略掉进程所占据的资源。比如说,同样一个程序,同一时刻被两次运行了,那么他们就是两个独立的进程。linux下查看系统进程的命令是ps。

2、进程在内核中的描述:在linux中,有一个结构体task_struct,被专门用来描述进程的信息。在2.4版本及其以前,task_struct与内核堆栈是放在同一个4K的页面中,如下: union task_union{ struct task_struct task; unsigned long stack [INIT_TASK_SIZE/sizeof(log)]; }; 这样有一个好处,就是在内核中运行的时候,任何时候都可以通过指针得到当前运行进程的task_struct。尽管这给进程管理带来了好处,不过也有很大的隐患,如果task_struct越来越大,或者内核堆栈压的太多(函数调用层次太多),就不行了。所以从linux2.6开始,就有所改变了。首先是将这个4K的页面增加到8K:#defineTHREAD_SIZE (8192),然后又这样一句代码:#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE,GFP_KERNEL)。然后还有一个很大的改变,那就是把task_struct从这部分空间中移走,然后抽象出一个thread_info的结构(里面是经常被访问的变量): struct thread_info{ struct task_struct *task; //main task structure ...... //还有几个其他的选项 } 这样,thread_info就代替了原来task_struct的位置,和内核堆栈共享8K的空间。从上面的描述中也可以看到thread_info里面有一个指针,指向了task_struct。通过这两个方式,就可以解决上面提到的隐患问题。

3、进程的状态转换:在linux中,有两个变量用来表示内核的状态,volatile long state 用来表示进程的可运行性,long exit_state用来表示进程退出时的状态。此外,关于进程的详细状态,参见下面的宏定义: #define TASK_RUNNING 0 //正在运行的进程; #define TASK_INTERRUPTIBLE 1 //等待资源的进程,当等待的资源有效时被唤醒,也可由其他进程或内核用信号中断、唤醒后进入就绪状态 #define TASK_UNINTERRUPTIBLE 2 //同上,但是不能被其他进程或者内核中断 #define TASK_STOPPED 4 //进程被暂停,一般是收到了SIGSTOP/SIGTSTP/SIGTTIN/SIGTTOU信号,通过其他进程的信号才能被唤醒 #define TASK_TRACED 8 //进程被跟踪,一般在调试的时候会用的 //in tsk->state again #define EXIT_ZOMBIE 16 //僵死状态,虽然释放了内存文件等资源,但内核中仍然保存task_struct,等待父进程调用wait4()或者waitpid()函数来回收 #define EXIT_DEAD 32 //进程消亡前最后一个状态,父进程已调用了wait4()或waitpid() //in tsk->state again #define TASK_NONINTERACTIVE 64 //不是交互式进程,调度的时候会考虑到 至于进程间的转换,这里就不描述了。

4、进程标志位:为了对每个进程进行更细粒度的控制,在task_struct中还有一些变量flags: unsigned long flags ;//per process flags,defined blow 这个flags可以是下面的一些标志的组合:
#define PF_ALIGNWARN 0x00000001 /* Print alignment warningmsgs*/
#define PF_STARTING 0x00000002 /* being created */
#define PF_EXITING 0x00000004 /* getting shut down */
#define PF_DEAD 0x00000008 /* Dead */
#define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */
#define PF_SUPERPRIV 0x00000100 /* used super-user privileges */
#define PF_DUMPCORE 0x00000200 /* dumped core */
#define PF_SIGNALED 0x00000400 /* killed by a signal */
#define PF_MEMALLOC 0x00000800 /* Allocating memory */
#define PF_FLUSHER 0x00001000 /* responsible for disk writeback */
#define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */
#define PF_FREEZE 0x00004000 /* this task is being frozen for suspend now */
#define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */
#define PF_FROZEN 0x00010000 /* frozen for system suspend */
#define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */
#define PF_KSWAPD 0x00040000 /* I am kswapd */
#define PF_SWAPOFF 0x00080000 /* I am in swapoff */
#define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */
#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */

5、进程的调度策略:在task_struct中与进程调度相关的变量是:unsigned long policy,有三种调度策略: #define SCHED_NORMAL 0 #define SCHED_FIFO 1 #define SCHED_RR 2 不过这里有点问题,我下的2.6源码中就这三种调度策略,但是我看到有的书上介绍2.6内核的时候说到此外还有一种调度策略:SCHED_BATCH,说该调度策略一般是用于后台处理进程,没有交互性。FIFO与RR属于实时调度,所以优先级高于另外两种。 进程的调度优先级: int prio,static_prio; unsigned long rt_priority; prio是进程的动态优先级,随着进程的运行而改变,调度器有时候还会根据进程的交互性、平均睡眠时间而进行奖惩。默认情况下,实时进程(FIFO,RR)的动态优先级为0到99,另外两种是100到139,0最高,139最低。static_prio是普通进程的静态优先级,默认是120,rt_priority是实时进程的静态优先级。

6、ID相关:getpid():返回该进程的ID,getppid():返回该进程的父进程的ID。此外,在task_struct里面还维护了一些跟文件系统权限相关的一些变量: uid_t uid:创建这个进程的用户ID。每个用户有自己的访问权限,所以每个用户有自己的ID,root用户ID为0; uid_t euid:(effictive id,有效ID),系统是通过euid来判断该进程的权限的,一般情况下euid和uid是一样的,但是某些时候,进程需要以可执行文件的属主来运行那个程序,而不是可执行程序的用户来执行,那么euid就是那个可执行文件的属主的用户id。 uid_t suid:(saved set-user-ID),有时候必须通过系统调用来改变uid和gid的时候,用suid来保存真实的uid; uid_t fsuit:内核检查进程对于文件系统的访问时所参考的位,一般等同于euid。 此外,对应的有组id:gid_t gid,egid,sgid,fsgid。和上面的用户id是同类型的。
1条评分
惊鸿一剑 电魂 +1 期待你的下一篇 2009-05-28