进程像高管函数必备头文件
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h> //exit 的头文件
#include <unistd.h> //_exit 的头文件
1. 进程创建函数
pid_t fork(void);
作用:它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
返回值:这个函数有2个返回值;在不同的进程里面返回值是不同的。
在成功的情况下:
在父进程里面:返回值为子进程的进程号;
在子进程里面:返回值为0;
失败:返回值为-1;
2. 获取的进程id号
pid_t getpid(void); //获取当前进程的ID号;
pid_t getppid(void); //获取当前进程的父ID号;
作用:获取当前进程的进程ID号。
返回值:对应的ID号
3.等待子进程退出并且执行清理工作
pid_t wait(int *status); //随机的等待一个子进程退出
pid_t waitpid(pid_t pid, int *status, int options);//等待指定的pid子进程退出;
功能:执行上面的函数都是暂停进程,等待子进程退出执行清理工作;
形式参数:
pid:子进程id号;
status:传出参数,它会将子进程的结束状态值保存到status指向的变量里;
options:用于改变 waitpid 的行为。其中最常用的是 WNOHANG,它表示无论子进程是否退出都将立即返回,不会将调用者的执行挂起。
返回值:对应的子进程的id号;
4.exec函数族
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
作用:运行第一个exec函数族指定的可执行程序。
形式参数:
path:包括执行文件名的全路径名,比如"/bin/ls"。
file:既可是全路径名也可是可执行文件名,比如"ls"。
arg:是可执行文件的全部命令行参数,可以用多个,包含命令名本身。注意最后一个参数必须为 NULL。
argv:是一个字符串数组。是可执行文件的全部命令行参数数组。比如,char *argv[]={“full path”,”param1”,”param2”,…NULL};
返回值:没有作用,因为程序跑去执行组函数了,没有办法处理返回值。
例子:
execl("/bin/ls", "ls", "-l", NULL);
execlp("ls", "ls", "-l", NULL);
char *str[] = {"ls", "-l", NULL}; execv("/bin/ls", str);
char *str[] = {"ls", "-l", NULL}; execvp("ls", str);
5.终止进程
void exit(int status);
void _exit(int status);
作用:都是用来终止进程的。
形式参数:
status:利用这个参数传递进程结束时的状态。一般来说, 0 表示正常结束;其他的数值表示出现了错误,进程非正常结束。
exit 函数和_exit 函数的区别:
exit函数:在退出之前会检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的“清理 I/O 缓冲”。
_exit 函数:直接将进程关闭,缓冲区中的数据就会丢失。
因此,如想保证数据的完整性,建议使用exit 函数。
例子:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
pid_t pid = fork();
if(pid> 0)//父进程
{
int a;
for(a=0;a<15;a++)
{
printf("父进程执行了%d次\r\n",a);
}
}
else fi(pid==0)//子进程
{
for(a=0;a<10;a++)
{
printf("子进程执行了%d次\r\n",a);
if(a==8)
{
printf("子进程退出\r\n");
exit (0);//当子进程执行8次时,退出。
}
}
return 0;
}