Linux系统中至少有一个进程,一个程序可以对应多个进程,一个进程只能对应一个程序
PCB:进程控制块
进程组:
一、进程和线程得关系
二、创建进程
#include "sys/types.h"//pid_t在该头文件中
#include "unistd.h"
pid_t fork(void);
父进程和子进程能能获取fork的返回值,父进程获取到的返回值是子进程的进程号,子进程获取到的返回值是0。
fork函数创建子进程后,会复制父进程得数据段、代码段和堆栈空间等到子进程得空间。同时子进程会共享父进程打开得文件。
三、等待进程结束
创建子进程之后,父进程和子进程间运行关系如下图。在整个系统中,所有的进程的进程推出之后都会由他的父进程回收资源,由于在创建了子进程之后,父子进程的运行是无序的。如果父进程先于子进程推出,就会导致子进程的资源无法释放,因此就需要一种方法需要让父进程知道子进程什么时候结束。
#include "sys/types.h"
#include "sys/wait.h"
/*
* pid: pid <- 1:等待所有其进程组标识等于pid绝对值的子进程
* pid = -1:等待任何子进程
* pid = 0: 等待任何其组标识等于调用线程组标识的进程
* pid > 0:等待其进程标识等于pid的进程
* ststus:标识子进程的返回状态(以何种方式结束)
* options:可选函数执行方法,通常使用0,也可用如下或运算组合
* WNOHANG:如果没有子进程退出,立即返回
* WUNTRACED:如果有处于停止状态的进程将导致调用返回
* WCONTINUED:如果停止了的进程由于SIGCONT信号的到来而继续运行,调运将返回
**/
pid_t waitpid(pid_t pid, int *status, int options)
四、退出进程
#include "stdlib.h"
int exit(int status);
int atexit(void (*function)(void) );
int on_exit(void (*function)(int , void *), void *arg);
#include "unistd.h"
void _exit(int status);
- exit():退出当前进程并且尽可能的释放当前进程占用的资源
- _exit():退出当前进程,不尝试释放资源
- atexit():退出时指定调用用户代码,并且可以给一个程序设置多个退出时调用的函数,该接口以栈方式向系统注册,因此后注册的函数先调用
- on_exit():退出时指定调用用户代码,并可以为调用的函数设定参数
五、进程管道通信示例
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
#include "sys/wait.h"
int main()
{
pid_t pid;
int fd[2];
char *cmd="exit";
char buf[64];
if(pipe(fd))
{
printf("pipe init faild\n");
return 0;
}
pid = fork();
if(pid==-1)
{
printf("fork init faild\n");
return 0;
}
if(pid == 0)
{
printf("son!!\n");
while(1)
{
close(fd[1]);//Write
read(fd[0],buf,sizeof(buf));
close(fd[0]);
if(strcmp(buf,cmd) == 0)
{
printf("wait ok\n");
exit(0);
}
printf("wait\n");
sleep(1);
}
}
else if(pid > 0)
{
printf("parent\n");
sleep(5);
close(fd[0]);
write(fd[1],cmd,strlen(cmd));
close(fd[1]);
waitpid(pid,NULL,0);
printf("over\n");
}
}