exec函数族
man exec ~~~
int execl(const char*path,const char arg,…)
int execlp(const charfile,const char * arg,…)
后缀中
v 命令行参数中的argv
e environment,需要添加环境变量表
l list
//execlp 实现ls -al
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid;
pid=fork();
if(pid<0){
perror("fork err!");
exit(1);
}else if(pid==0){
// printf("son process");
execlp("ls","ls","-al",NULL);
}else {
wait(NULL);
printf("This is father process\n");
}
return 0;
}
重定向输出函数 dup2(3,1) 将STD_OUT输出重定向到3的文件中。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(){
pid_t pid;
pid=fork();
//打开ps.out文件
int fd=open("ps.out",O_WRONLY|O_CREAT|O_TRUNC,0644);
if(pid<0){
perror("fork err\n");
exit(1);
}else if (pid >0){
wait(NULL);
printf("Father process! !!!!!!!\n");
}else{
dup2(fd,STDOUT_FILENO); //== dup2(fd,1);
execlp("ps","ps","-aux",NULL);
printf("Son process ends!!!!!!!!!\n");
}
return 0;
}
孤儿进程
//父进程终止后,子进程的父进程变成pid=1的进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid;
pid=fork();
if(pid==-1){
perror("fork error!\n");
}else if (pid==0){
printf("child=%d parentid=%d\n",getpid(),getppid());
sleep(3);
printf("child=%d parentid=%d\n",getpid(),getppid());
}else {
printf("father id=%d",getpid());
}
return 0;
}
僵尸进程
进程终止,父进程尚未回收,子进程残留资源存放于内核中,变成僵尸进程。注:僵尸进程已经终止,无法用kill清除!。
wait函数三个作用:阻塞等待子进程退出;回收子进程残留资源;获取子进程结束状态。
//子进程未得到处理 结束后成为僵尸进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid;
pid=fork();
if(pid<0){
perror("fork error!\n");
exit(1);
}else if (pid==0){
printf("child=%d parentid=%d\n",getpid(),getppid());
sleep(3);
printf("----------son process died--------------\n");
}else {
while(1){
printf("father id=%d son proce%d\n",getpid(),pid);
sleep(1);
}
}
return 0;
}
进程退出的宏:
WIFEXITED(status) 非0 则进程正常结束
WEXITSTATUS(status) 若上述宏非0 则获取进程退出状态(exit 参数)。
WIFSIGNALED(status) 非0 则进程异常终止
WTERMSIG(status) 若上述宏非0 则使用该宏获取进程终止进程的信号。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid;
int status;
pid=fork();
if(pid<0){
perror("fork error!\n");
exit(1);
}else if (pid==0){
printf("child=%d parentid=%d\n",getpid(),getppid());
sleep(3);
printf("----------son process died--------------\n");
exit(22);
}else {
pid_t wpid=wait(&status);
if(wpid==-1){
perror("wait error!\n");
exit(1);
}
//使用宏
if(WIFEXITED(status)){
printf("child exit with %d\n",WEXITSTATUS(status));
}
while(1){
printf("father id=%d son proce%d\n",getpid(),pid);
sleep(1);
}
return 0;
}
}
//执行该程序时,根据输出的子进程pid,向其发送kill信号 退出值15
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(){
pid_t pid;
int status;
pid=fork();
if(pid<0){
perror("fork error!\n");
exit(1);
}else if (pid==0){
printf("child=%d parentid=%d\n",getpid(),getppid());
sleep(13);
printf("----------son process died--------------\n");
exit(22);
}else {
pid_t wpid=wait(&status);
if(wpid==-1){
perror("wait error!\n");
exit(1);
}
//使用宏
if(WIFEXITED(status))
printf("child exit with %d\n",WEXITSTATUS(status));
if(WIFSIGNALED(status))
printf("child unormally eixted with signal%d\n",WTERMSIG(status));
while(1){
printf("father id=%d son proce%d\n",getpid(),pid);
sleep(1);
}
return 0;
}
}
wait函数只能回收最先结束的子进程,要想回收多个子进程,可用waitpid函数指定回收。
pid_t waitpid(pid_t pid,int *status,int options); 指定第三个参数可以不阻塞。
pid参数:
-
0 回收指定pid的子进程
- -1 回收任意子进程 相当于wait
- 0回收和当前调用wiatpid一个组的所有子进程 通常情况下,父子进程同组,使用等于-1
- <-1 回收指定进程组内的任意子进程
参数3若为WNOHANG,非阻塞
//下图所示,pid为7367的子进程被回收,其他子进程处于未处理状态。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc,char *argv[]){
int n=5,i;
pid_t p1,p2;
if(argc==2)
n=atoi(argv[1]);
for(i=0;i<n;i++){
p1=fork();
if(p1==0)
break; //若是子进程则结束循环 i永远为0
else if(i==3)//单独回收第三个子进程的情况。先保存pid
p2=p1;
}
if(n==i){
sleep(n);
printf("This is parent,pid=%d\n",getpid());
waitpid(p2,NULL,0);
while(1);
}else{
printf("This is child ,pid=%d and parentpid=%d\n",getpid(),getppid());
}
//waitpid 持续等待所有子进程结束。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc,char *argv[]){
int n=5,i;
pid_t p1,p2;
pid_t wpid;
if(argc==2)
n=atoi(argv[1]);
for(i=0;i<n;i++){
p1=fork();
if(p1==0)
break; //若是子进程则结束循环 i永远为0
else if(i==3)//单独回收第三个子进程的情况。先保存pid
p2=p1;
}
if(n==i){
sleep(n);
printf("This is parent,pid=%d\n",getpid());
do{
//若wpid为0 则子进程仍在执行。 -1表示尽可能的回收
wpid=waitpid(-1,NULL,WNOHANG);
if(wpid>0) n--; //每结束一个子进程 n--
}while(n!=0); //n=0 所有子进程结束。
// while(1);
}else{
printf("This is child ,pid=%d and parentpid=%d\n",getpid(),getppid());
}
//return 0;
}