进程数据块(task_struct)
task_struct是Linux内核的⼀种数据结构,它会被装载到RAM(随机存储器)里并且包含着进程的信息。
每个进程都把它的信息放在 task_struct 这个数据结构里
task_struct 包含了这些内容:
标示符 : 描述本进程的唯⼀标示符,用来区别其他进程。
状态 :任务状态,退出代码,退出信号等。
优先级 :相对于其他进程的优先级。
程序计数器:程序中即将被执行的下一条指令的地址。
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:进程执行时处理器的寄存器中的数据。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
可执行程序与进程内存映像的不同之处在于:
a. 可执行程序位于磁盘中而内存映像位于内存;
b. 可执行程序没有堆栈,因为程序被加载到内在中才会分配堆栈;
c. 可执行程序虽然也有未初始化数据段但它并不被存储在位于硬盘中的可执行文件中;
d. 可执行程序是静态的、不变的,而内在映像随着程序的执行是在动态变化的,数 据段随着程序的执行要存储新的变量值,栈在函数调用时也是不断在变化。
环境变量
环境变量字符串都是name=value 这样的形式。一 般把name的部分叫做环境变量,value 的部分则是环境变量的值。
environ指针:可以查看所有环境变量字符串 。
getenv函数 :如果给出name要在环境变量 表中查找它对应的value。
修改环境变量可以用以下函数 :putenv和setenv函数若成功则返回为0,若出错则返回非0。
进程的状态
运行状态:进程要么在运行中 ,要么在运行队列中。
死亡状态:是内核运行中 do_exit() 函数的返回的状态 。
僵死状态:进程退出,并且父进程没有读到子进程退出的返回代码时就会产生僵死进程。
睡眠状态:进程等待事件的完成(可中断睡眠状态) 。
磁盘休眠状态:通常等待I/O结束(不可中断睡眠状态)。
进程的优先级
Linux/unix中:ps -l命令可以查看自己bash的相关进程。
UID : 代表执行者的⾝身份 。
PID : 代表这个进程的代号 。
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号 。
PRI :代表这个进程可被执行的优先级,其值越小越早被执行。
NI :代表这个进程的nice值。
PRI(new)=PRI(old)+nice。这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。到目前为止,更需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念, 但是进程nice值会影响到进程的优先级变化。
进程内存布局分为四个不同的段:
• 文本段,包含程序的源指令。
• 数据段,包含了静态变量。
• 堆,动态内存分区区域。
• 栈,动态增长与收缩的段,保存本地变量。
创建子进程,子进程会拷贝父进程中的数据段、共享库、栈和堆,子进程独立可以修改这些内存段,但是文本段是父进程和子进程共享的内存段,不能被子进程修改。
僵尸进程:一个子进程在父进程没有调用wait()或者waitpid()的情况下退出,这个子进程就是僵尸进程,如果其父进程还存在而一直不调用wait(),则该僵尸进程将无法回收,等到其父进程退出后该进程将被init回收。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程收养,并由init进程对它们完成状态收集工作。
进程环境
进程终止
进程终止的方式有8种,前5种为正常终止,后三种为异常终止:
1 从main函数返回;
2 调⽤用exit函数;
3 调⽤用_exit或_Exit;
4 最后一个线程从启动例程返回;
5 最后一个线程调⽤用pthread_exit;
6 调⽤用abort函数;
7 接到一个信号并终止;
8 最后一个线程对取消请求做出响应。
环境表
每个进程都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以'\0'结尾的环境字符串,环境指针是一个全局变量,指向指针数组的地址。
存储器分配
malloc函数分配指定字节数的存储区,该存储区中的初始值不确定;calloc函数为指定数量 且指定长度的对象分配存储空间,该空间中的每⼀一位都初始化为0;realloc函数更改存储区的 长度(增加或减少),新增区域内的初始值不确定,如果ptr为空,realloc和malloc的功能相同。
进程标识符
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); //返回值:调⽤用进程的进程ID
pid_t getppid(void); //返回值:调⽤用进程的⽗父进程ID
uid_t getuid(void); //返回值:调⽤用进程的实际⽤用户ID
uid_t geteuid(void); //返回值:调⽤用进程的有效⽤用户ID
gid_t getgid(void); //返回值:调⽤用进程的实际组ID
gid_t getegid(void); //返回值:调⽤用进程的有效组ID
实际用户和有效用户
1>实际用户ID和实际用户组ID:标识我是谁,也就是登录用户的uid和gid。
2>有效用户ID和有效用户组ID:进程用来决定我们对资源的访问权限。