Linux - 进程
1.Linux进程的相关概念
程序:静态的概念,它是一个编译好的二进制文件。
进程:动态的概念,当程序运行的时候,系统会自动运行一个对应进程。进程包含了进程控制块(PCB),
代码段,数据段三个部分。 进程控制块:在linux中是用一个结构体来表示的。
僵尸进程:父进程优先于子进程退出。如果你创建了子进程,但是在父进程中没有回收该子进程的资源,
那么该子进程就会变成僵尸进程,僵尸进程最终会由系统中一个叫做init的进程回收。
init进程:(1号进程)是系统启动的时候运行的第一个进程,它是所有进程的祖进程。
2.进程的接口函数
进程的创建fork()、vfork() 新创建的进程被称为子进程,它复制了父进程的所有资源,父子进程的执行顺序不确定。
函数分析:
#include <unistd.h>
pid_t fork(void);
return: > 0 处于父进程中,返回值是子进程进程id号
return: = 0 处于子进程中
return: < 0 创建进程出错
//栗子1:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main()
{
//程序本身就是一个进程,称为父进程
pid_t pro_pid;
printf("In father process!Pid = [%d]\n", (int)getpid());
// 创建一个子进程
pro_pid = fork();
if(pro_pid<0)
{
perror("Create process failed!\n");
return -1;
}
// 子进程
else if(pro_pid == 0)
printf("In child process!Pid = [%d]\n", (int)getpid());
else
printf("Return father process!\n");
printf("Exit!\n");
wait(NULL); //回收子进程
return 0;
}
运行结果:
- Vfork( )函数
子进程共享了父进程的所有资源,与fork不同的是 先是运行子进程,然后再运行父进程运行。也不受sleep让出cpu的影响。
//栗子2:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
int main()
{
pid_t pro_pid;
printf("In father process!Pid = [%d]\n", (int)getpid());
// 创建一个子进程
pro_pid = vfork();
if(pro_pid<0)
{
perror("create process failed!\n");
return -1;
}
// 子进程
else if(pro_pid == 0)
{
sleep(2);//阻塞,人为的干扰了cpu时间片的分配,主动让出cpu资源
printf("In child process!Pid = [%d]\n", (int)getpid());
exit(0);
}
else
printf("I am return father process!\n");
printf("Exit!\n");
wait(NULL); //回收子进程
return 0;
}
运行结果:
分析:
可以看到进入父进程后创建子进程,然后等子进程运行结束在运行父进程!
3. 进程回收、退出函数 exit( )、_exit( )
#include <stdlib.h>
void exit(int status);
参数status 为进程退出时的状态
status在实际编写程序中是可以自己约定的
比如:
exit(2)----》出现打开文件错误
exit(3)----》出现段错误(逻辑错误)
exit(0)----》正常退出
exit()在退出的时候会刷新IO缓冲区,然后才退出(负责任的退出)
_exit() 直接退出(不负责任的退出)
4. 等待子进程退出wait()、waitpid()
#include <sys/wait.h>
pid_t wait(int *stat_loc);
返回值:你回收的那个子进程的id号
参 数:stat_loc 子进程退出时的状态信息(不仅仅只是返回值)
stat_loc 里面不仅仅只是保存了exit退出时的数值,它还保存了子进程退出时是哪个信号让它退出的,出错了是什么原因导致的。
pid_t waitpid(pid_t pid, int *stat_loc, int options); 回收子进程/进程组
参数:pid 回收的子进程的id
pid<-1 等待进程组号为-pid中的某个子进程退出
pid=-1 等待任意一个子进程
pid=0 等待本进程组中的某个子进程退出
options ----》 一般设置为0
5. 获取进程的id
获取当前进程id
#include <unistd.h>
pid_t getpid(void); 返回值:就是当前进程的id号
获取父进程id
#include <unistd.h>
pid_t getppid(void); 返回值:就是父进程的id号