进程函数接口
单进程程序 只能一行一行代码地去执行!
为了可以实现同时处理多个任务,那么引入多进程。
如何创建新的进程? 使用 fork()
man 2 fork
功能:create a child process -> 创建新的子进程
使用格式:
#include <unistd.h>
pid_t fork(void);
参数: 无
返回值: pid_t -> PID号类型 -> %d
成功: 父进程返回子进程的PID号
子进程返回0
失败:-1 没有创建出子进程
#include <stdio.h>
int main()
{
fork(); //创建子进程
printf("helloworld!\n");
return 0; //当父进程执行到return 0代表程序结束,返回一个linux命令行。
}
结果1: 父进程先执行完退出了,子进程才开始
helloworld! 父进程打印出来
$ helloworld!
命令行由于父进程执行return 0退出了而返回的
helloworld是子进程打印出来的
结果2: 子进程先执行完,再到父进程执行,然后父进程退出。
ubuntu:$ ./fork_demo
helloworld! 子进程打印
helloworld! 父进程打印
命令行由于父进程执行return 0退出了而返回的
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t x;
x = fork();
if(x > 0) //父进程
{
usleep(100000);
printf("helloworld!\n");
}
if(x == 0)//子进程
{
printf("apple!\n");
}
return 0;
}
结论:使得父子进程处理不同的任务,只需要判断返回值即可!
查看自身的PID号以及父进程的PID号
getpid() getppid() -> man 2 getpid
功能: 获取ID号 get process identification
使用格式:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void); -> 获取自身ID
pid_t getppid(void); -> 获取父进程ID
参数: 无
返回值: getpid() 返回值自身的ID号
getppid() 返回父进程的ID号
练习2: 在父进程中打印自己与孩子的PID号,在子进程中打印自己与父亲的PID号。要求子进程先执行。
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t x;
x = fork();
if(x > 0) //父进程
{
usleep(100000);
printf("parent pid = %d\n",getpid());
printf("child pid = %d\n",x);
}
if(x == 0)//子进程
{
printf("apple!\n");
printf("child pid = %d\n",getpid());
printf("parent pid = %d\n",getppid());
}
return 0;
}
验证孤儿进程的父进程是祖先进程。
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t x;
x = fork();
if(x > 0) //父进程
{
sleep(2); //2秒之后,子进程就是一个孤儿进程
}
if(x == 0)//子进程
{
printf("my parent id = %d\n",getppid()); //id = 2892
sleep(5);
printf("my parent id = %d\n",getppid()); //id = 1
printf("helloworld!\n");
}
return 0;
}
- 父进程主动回收子进程的资源 -> wait() -> man 2 wait
功能: 使得子进程改变状态 wait for process to change state -> 子进程从僵尸态变成死亡态
使用格式:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
status:填int*指针,那么指针保存子进程的退出状态
填NULL,不关注子进程的退出状态,只回收资源
返回值:
成功: 退出的子进程的ID
失败: -1
例题: 父进程还在,并且主动回收资源。
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t x;
x = fork();
if(x > 0) //父进程
{
wait(NULL); //阻塞等待子进程的退出,然后再帮子进程回收资源。
printf("hello!\n");
}
if(x == 0)//子进程
{
printf("apple!\n"); //退出时有父进程帮自己回收资源,所以我就不找继父。
}
return 0;
}