进程控制块(PCB)结构

一、进程控制块(PCB)结构

进程控制块(PCB)是系统为了管理进程设置的一个专门的数据结构。系统用它来记录进程的外部特征,描述进程的运动变化过程。同时,系统可以利用PCB来控制和管理进程,所以说,PCB(进程控制块)是系统感知进程存在的唯一标志。

 Linux系统的PCB包括很多参数,每个PCB约占1KB多的内存空间。用于表示PCB的结构task_struct简要描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
include/linux/sched.h
struct task_struct {
 volatile long state;
 struct thread_info *thread_info;
 atomic_t usage;
unsigned long flags;
unsigned long ptrace;
 
 int lock_depth;
 
 int prio, static_prio;
 struct list_head run_list;
 prio_array_t *array;
 
 unsigned long sleep_avg;
 long interactive_credit;
 unsigned long long timestamp;
 int activated;
 
 unsigned long policy;
 cpumask_t cpus_allowed;
 unsigned int time_slice, first_time_slice;
 
struct list_head tasks;
 struct list_head ptrace_children;
 struct list_head ptrace_list;
 
 struct mm_struct *mm, *active_mm;
...
 struct linux_binfmt *binfmt;
 int exit_code, exit_signal;
 int pdeath_signal;
...
 pid_t pid;
 pid_t tgid;
...
struct task_struct *real_parent;
struct task_struct *parent;
struct list_head children;
 struct list_head sibling;
 struct task_struct *group_leader;
...
 struct pid_link pids[PIDTYPE_MAX];
 
 wait_queue_head_t wait_chldexit;
 struct completion *vfork_done;
 int __user *set_child_tid;
 int __user *clear_child_tid;
 
 unsigned long rt_priority;
 unsigned long it_real_value, it_prof_value, it_virt_value;
 unsigned long it_real_incr, it_prof_incr, it_virt_incr;
 struct timer_list real_timer;
 unsigned long utime, stime, cutime, cstime;
 unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
 u64 start_time;
...
 uid_t uid,euid,suid,fsuid;
  gid_t gid,egid,sgid,fsgid;
 struct group_info *group_info;
 kernel_cap_t cap_effective, cap_inheritable, cap_permitted;
 int keep_capabilities:1;
 struct user_struct *user;
...
 struct rlimit rlim[RLIM_NLIMITS];
 unsigned short used_math;
 char comm[16];
...
 int link_count, total_link_count;
...
 struct fs_struct *fs;
...
 struct files_struct *files;
...
 unsigned long ptrace_message;
 siginfo_t *last_siginfo;
...
 };
调度数据成员:
1) vo latile long state
表示进程的当前状态。进程运行时, 它会根据具体情况改变状态。进程状态总共有TASK RUNN ING ( 可运行状态)、TASK INTERRUPT IBLE ( 可中断的等待状态)、TASK UNINTERRUPT IBLE(不可中断的等待状态)、TASK ZOMB IE( 僵死状态)、TASK STOPPED(暂停状态) 等5种。
2) long pr io rity进程优先级, prio rity 的值给出了进程每次获取CPU 后, 可使用的时间片长度( 单位是jiffies)。
3) unsigned long rt_priority rt_priority 的值给出了实时进程的优先级, rt_priority 
1000给出进程每次获取CPU 后, 可使用的时间片长度(单位是jiffies)。
4) long counter在轮转法调度时counter表示当前进程还可运行多久。在进程开始时被赋为priority的值, 以后每隔一个时钟中断递减1,减到0时引起新一轮调度。
5) unsigned long policy表示该进程的进程调度策略。调度策略有:
SCH ED_OTHER 0, 非实时进程, 用基于优先权的轮转法。
SCH ED_FIFO 1, 实时进程, 用先进先出算法。
SCH ED_RR 2, 实时进程, 用基于优先权的轮转法
 
进程队列指针:
1) struc t task_struct* next_task, * prev_task
在Linux 中所有进程(以PCB 的形式)组成一个双向链表,
next_task和prev_task是链表的前后向指针。
2) struct task_struct* p_opptr, * p_pptr
struct task_struc t* p_cptr, * p_ysptr, * p_osptr
以上分别是指向该进程的原始父进程、父进程、子进程和新
老兄弟进程的指针。
3) struct task_struct* pidhash_next
struct task_struct** pidhash_pprev
用于链入进程hash表的前后指针。系统进程除了链入双
向链表外, 还被加到hash表中。
 
进程标识:
uid_t uid  gid_t gid uid和gid分别是运行进程的用
户标识和用户组标识。
pid_t pid  pid_t pgrp pid和pgrp分别是运行进程的
进程标识号和进程组标识号
时间数据成员:
long per_cpu_utime [ NR_CPUS ] per_cpu_stime
[ NR_CPUS]
per_cpu_utime 是用户态进程运行的时间, per_cpu_
stime是内核态进程运行的时间
进程创建时间unsigned long start_time

文件系统数据成员:
struct fs_struct* fs
fs保存了进程本身与VFS( 虚拟文件系统)的关系信息。
struct fs_struct
{
 atom ic_t count;
 rw lock_t lock;
 int umask;
 struct dentry* root, * pwd, * altroot;
 struct vfsm ount* rootmnt, * pwdmnt, * altrootmnt;
}
其中root、rootm nt是根目录的dentry 和其mount点的vfsmount。
pwd、pwdmnt 是当前工作目录的dentry 和其mount 点的vfs..
mount。altroot、altrootmnt是保存根节点被替换之后原来根目标
的dentry和其mount点的vfsmount。
 
内存数据成员:
1) struct mm_struct* mm
在Linux 中, 采用按需分页的策略解决进程的内存需求。
task_struct的数据成员mm 指向关于存储管理的mm_truc t结
构。
2) struct mm_struct* active_mm
active_mm 指向活动地址空间。
3) mm_segm ent_t addr_ lim it
表示线程空间地址。
用户线程空间地址: 0..0xBFFFFFFF。
内核线程空间地址: 0..0xFFFFFFFF
4) spinlock_t alloc_ lock
用于申请空间时用的自旋锁。自旋锁的主要功能是临界区
保护。
 
页面管理:
1) int swappable: 1
进程占用的页面是否可换出。swappab le为1表示可换出。
2) unsigned long min_flt, maj_ flt
该进程累计minor缺页次数和major缺页次数。
3) unsigned long nswap
该进程累计换出页面数。
4) unsigned long swap_cnt
下一次循环最多可换出的页数。

 

二、makefile

makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具.

Makefile来告诉make命令如何编译和链接这几个文件。规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

下面举一个简单的例子:(进度条的实现)

1.vim proc.c写入(进度条的实现)

 2、vim Makefile写入

 

第一行中并没有任何参数,只是在冒号(:)后列出编译中所需的文件,当第一行中的任何文件中更改时,make就知道需要重新编译了。

其中.PHONY意思表示clean是一个“伪目标”,清除 所有 .o文件 ,.o文件就是目标文件

3、执行make指令就可以编译proc.c这个程序

posted @ 2017-11-01 20:45  专注it  阅读(1866)  评论(0编辑  收藏  举报