进程标识符
进程ID,类似每个人的身份证号码。根据进程ID,用户可以精确地定位一个进程。
进程标识符的类型pit_t,本质是一个无符号整型。
进程标识符与进程是一对一的关系,进程标识符和程序是多对一的关系。
进程标识符1——–>进程1———>程序1
进程标识符2——–>进程2———>程序1
同一个程序文件可以加载多次成为不同的进程。进程中重要的ID值
每个进程都有6个重要的ID值,分别是进程ID,父进程ID,有效用户ID,实际用户ID,有效组ID,实际组ID。
#include<unistd.h>
pit_t getpid(void);//获取进程ID值
pit_t getppid(void);//获取父进程ID值
uit_t getuid(void);//获取实际用户ID值
uid_t geteuid(void);//获取有效用户ID值
gid_t getgid(void);//获取组用户ID值
gid_t getegid(void);//获取有效组用户ID值
以上六个获取ID值函数,成功则返回ID值,失败则返回-1.
- 创建一个进程
linux系统允许任何一个用户进程创建一个子进程。该自己成存在于系统之中,独立于父进程。linux环境下使用fork函数创建一个新的进程。
#include<unistd.h>
pit_t fork(void);//fork函数原型
fork函数的返回值有三种情况;
1.对于父进程,fork()返回新创建的子进程的ID值。
2.对于子进程,fork()返回0.
3.出错,返回-1.
fork()创建了新的进程后,为这个新进程分配进程空间,并将父进程的数据段和堆栈段复制到子进程的进程空间中,并且和父进程共享代码段。共享代码段是因为代码段是只读的,不存在修改的问题。而数据段和堆栈段是可以修改的。
fork()函数的出错情况
1.系统中已经有太多的进程存在了。
2.调用fork()的用户的进程太多了。
一般系统对一个用户所创建的进程数会有限制,不然恶意用户会利用此攻击系统,导致系统崩溃。创建一个共享空间的子进程
#include<unistd.h>
pid_t vfork();
vfork和fork的区别:
1.vfork函数产生的子进程和父进程完全共享地址空间。包括代码段,数据段,堆栈段,子进程对这些共享资源所做的修改,可以影响到父进程。
但fork函数对资源进行修改后,并不会影响到父进程,因为fork函数所产生的子进程只共享了父进程的代码段。
2.vfork函数所产生的子进程一定比父进程先运行。也就是说父进程调用了vfork函数后会等待子进程运行后再运行。但fork()函数的子进程和父进程运行时相互独立的。
注意:
不要在任何函数中调用vfork函数。线程同步问题。
- 退出进程
#include<stdlib.h>
void exit(int status);
当status为1时,表示发生错误时退出。
当status为0时,表示正常退出。
令可以将errno变量作为参数传递给exit含糊,这样配合echo $?命令,可以再程序退出后检查程序退出的原因。
- exit函数和_exit函数的区别
exit函数是一个标准的库函数,其内部封装了linux系统调用_exit函数。
区别:
exit函数会在用户空间做一些善后工作,例如,清理用户的I/O缓冲区,将其内容写入磁盘文件等,之后才进入内核释放用户进程的地址空间。
_exit函数直接进入内核释放用户进程的地址空间,所有用户空间的缓冲区内容都将丢失。