进程
创建子进程:fork调用,
一次fork调用返回两个值,1、返回子进程的pid(非负整数)
2、返回0
父进程的fork返回子进程的id,子进程的fork返回0(表示执行成功)
创建单个子进程:
pid_t pid; pid = fork(); if(pid == -1) { perror("fork error"); exir(1); }else if(pid == 0) { printf("I`m child pid = %u\n, ppid = %u\n", getpid(), getppid()); }else{ printf("I`m parent pid = %u\n, ppid = %u\n", getpid(), getppid()); }
循环创建多个子进程
for(...)
{
上述代码...在子进程中加入break
}
进程的有效用户与实际用户:当使用sudo后有效用户是root,实际用户是lr
uid_t getuid(void) //获取实际用户id
uid_t geteuid(void) //获取有效用户id
fork之后父子进程相同处:全局变量、.data(各自一份)、 .text、栈、堆、环境变量、用户id、宿主目录、进程工作目录、信号处理方式
不同处:进程id、fork返回值、进程运行时间、闹钟、未决信号集、各自的父进程id
全局变量各自独立,不互相影响
父子进程间遵循读时共享,写时复制的原则。父子进程读共有的数据时、使用同一数据。当有写操作时,复制一份数据各自使用。
重点:共享文件描述符(打开文件的结构体),可以操作同一个文件
mmap建立的映射区(通信使用)
gdb调试 默认跟踪的是父进程。
set follow-fork-mode child命令设置gdb在fork之后跟踪子进程
set follow-fork-mode parent 设置跟踪父进程
要在fork函数调用之前设置
孤儿进程、僵尸进程
孤儿进程: 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为init进程,称为init进程领养孤儿进程。
僵尸进程: 进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸(Zombie)进程。
特别注意,僵尸进程是不能使用kill命令清除掉的。因为kill命令只是用来终止进程的,而僵尸进程已经终止。