一、fork() 函数
用于从一个已存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。
头文件:
#include <sys/types.h>
#include <unistd.h>
pid_t child1,child2,father;
child1=fork();
函数格式 | pid_t fork(void); pid_t 为无符号整型 |
---|---|
参数 | 无 |
返回值 | 成功:子进程中返回0,父进程中返回子进程ID |
失败:返回-1 |
失败有两个原因:
1、当前的进程数已经达到了系统规定的上限,这时 errno 的值被设置为 EAGAIN。
2、系统内存不足,这时 errno 的值被设置为 ENOMEM。
二、waitpid() 函数
当调用waitpid()函数时,当指定等待的子进程已经停止运行或结束了,则waitpid()会立即返回;但是如果子进程还没有停止运行或结束,则调用waitpid()函数的父进程则会被阻塞,暂停运行。
头文件:
#include <sys/types.h>
#include <sys/wait.h>
函数格式 | pid_t waitpid(pid_t pid,int *status,int options); |
---|
1、参数 pid_t pid,其含义为:等待的子进程识别码
参数 | 说明 |
---|---|
pid<-1 | 等待进程组号为pid绝对值的任何子进程。 |
pid=-1 | 等待任何子进程,此时的waitpid()函数就退化成了普通的wait()函数。 |
pid=0 | 等待进程组号与目前进程相同的任何子进程,也就是说任何和调用waitpid()函数的进程在同一个进程组的进程。 |
pid>0 | 等待进程号为pid的子进程。 |
2、int *status,其含义为:保存子进程的状态信息,如果不关心子进程状态则设为NULL。
宏 | 说明 |
---|---|
WIFEXITED(status) | 如果子进程正常结束,它就返回真;否则返回假。 |
WEXITSTATUS(status) | 如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的结束代码。 |
WIFSIGNALED(status) | 如果子进程因为一个未捕获的信号而终止,它就返回真;否则返回假。 |
WTERMSIG(status) | 如果WIFSIGNALED(status)为真,则可以用该宏获得导致子进程终止的信号代码。 |
WIFSTOPPED(status) | 如果当前子进程被暂停了,则返回真;否则返回假。 |
WSTOPSIG(status) | 如果WIFSTOPPED(status)为真,则可以使用该宏获得导致子进程暂停的信号代码。 |
**3、**int options,其含义为:也可以控制waitpid()函数的行为,如果不需要可以设为0。
参数 | 说明 |
---|---|
WNOHANG | 如果pid指定的子进程没有结束,则waitpid()函数立即返回0,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号。 |
WUNTRACED | 如果子进程进入暂停状态,则马上返回。 |
附上代码段:
/***fork()&waitpid()***/
/*父进程、子进程之间的关系*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{
pid_t child1,child2,father;
child1=fork(); //创建子进程child1
if(child1 == (-1)) //child1创建失败处理
{
printf("child1 fork error\n");
exit(1); //异常退出
}
else if(child1 == 0)
{
printf("I am child1 program! and I execute 'ls -l'\n");
/*
* execlp 从PATH环境变量中查找相应的命令
* 成功不会返回,失败返回-1
*/
if(execlp("ls","ls","-l",NULL) == -1)
{
printf("execlp error\n");
}
}
/*在父进程中再创建进程child2,然后等待两个子进程的结束*/
else
{
child2=fork(); //创建child2进程
if(child2 == -1) //child2进程创建失败处理
{
printf("child2 fork error\n");
exit(1);
}
else if(child2 == 0)
{
printf("I am child2! and will sleep for 5s!\n");
sleep(5); //睡眠5s
printf("I am child2! and will exit!\n");
exit(0);
}
printf("I am father progress\n");
father=waitpid(child1,NULL,0);
/*阻塞式等待
*waitpid()函数
* 成功,则返回子进程的进程号;如果有错误发生,则返回-1
*/
if(father == child1)
{
printf("I am father progress.\n");
printf("I get child1 exit code:%d\n",child1);
}
else
{
printf("Father error!\n");
}
do
{
father=waitpid(child2,NULL,WNOHANG);//非阻塞式等待
if(father == 0)
{
printf("I am father progress.child2 has not exited!\n");
sleep(1);
}
}while(father == 0);
if(father==child2)
{
printf("I am father progress.\n");
printf("I get child2 exit code:%d\n",child2);
}
else
{
printf("Father error\n");
}
}
exit(0);
}
感谢。。。