赞
踩
1、fork()函数:创建子进程
pid_t fork(void);
无参数
返回值:
(pid_t 类型其实就是一个整型)
成功:
父进程返回,子进程id
子进程返回,0
失败:
-1 设置errno
2、execl()函数,execlp()函数:执行可执行文件,和系统命令
int execl(char* path,const char *arg,...);
参数:
path 可执行文件路径
arg 可以是多个,可以通过下面例子体现
返回值:
成功:不返回
失败:-1 errno
int execlp(char* file,const char *arg,...);
参数:
file 系统命令名
arg 可以是多个,可以通过下面例子体现
返回值:
成功:不返回
失败:-1 errno
3、wait函数和waitpid 回收子进程
每一个进程结束,都会在内存中残留一个PCB进程控制块,方便回收他的状态
pid_t wait(int* status);
参数:
status 传出参数,回收成功后,会返回进程的退出状态
返回值:
成功:子进程id
失败:-1
pid_t waitpid(pid_t pid,int *status,int options);
参数:
pid 指定某一个进程pid
status 传出参数,会返回进程状态
options WNOHANG不等待非堵塞
第一个参数传入值的作用
-1表示任意子进程
0 表示同组的所有进程
<-1 回收指定进程组内的任意子进程
返回值:
>0 表示成功回收的子进程pid
0 函数调用时,参数3指定WNOHANG,并且,没有子进程结束
-1 失败errno
总结:
wait、waitpid 一次调用,回收一个子进程,回收多个需要用while
使用fork创建三个子进程,
第一个子进程执行 ls -l 命令,
第二个子进程执行当前目录下的./test 可执行文件
第三个子进程打印文字到屏幕
父进程堵塞回收所有子进程 (第一种回收方式)
父进程不堵塞回收所有子进程(第二种回收方式)
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
void sys_error(const char* str)
{
perror(str);
exit(1);
}
int main(void)
{
pid_t pid;
int i;
// 循环创建三个子进程
for(i=0;i<3;i++)
{ // 返回0表示是,子进程就退出这个循环,不然子进程又会创建子进程
if((pid = fork())==0)
break;
if(pid == -1)
sys_error("fork error");
}
if(pid == 0) // pid为0,表示子进程
{
switch(i)
{
case 0:
printf("111111111111111111\n");
sleep(1); // 方便看效果
execlp("ls","ls","-l",NULL);
// 要是上面语句不报错,这条不会执行,因为他不会回来了
printf("111111111111111111\n");
break;
case 1:
printf("2222222222222222222\n");
sleep(1); // 方便看效果
execl("./test2","./test2",NULL);
// 要是上面语句不报错,这条不会执行,因为他不会回来了
printf("2222222222222222222\n");
break;
case 2:
printf("333333333333333333\n");
sleep(1); // 方便看效果
printf("子进程三打印\n");
printf("33333333333333333\n");
break;
}
}
else if(pid >0)
{
int status,wpid;
while ((wpid=waitpid(-1,&status,0))!= -1) //堵塞
{
printf("wpid = %d\n",wpid);
}
// while ((wpid=waitpid(-1,&status,WNOHANG))!= -1) // 不堵塞
// {
// printf("wpid = %d\n",wpid);
// }
// sleep(2);
printf("我是父进程\n");
}
return 0;
}
通过打印信息可以看出,他们不是一个进程执行完在执行另一个,他们会争取cpu
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。