linux作业三

 

exec函数族

使用fork()函数创建的子进程,其中包含的程序代码完全相同,只能根据fork()函数的返回值,执行不同的代码分支。
由exec函数族中的函数,则可以根据指定的文件名或路径,找到可执行文件。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    pid_t pid;
    pid=fork();
    if(pid ==-1)
    {
    perror("fork error");
    exit(1);
    }
    else if(pid>0)
    {
    printf("parent process:pid=%d\n",getpid());
    }
    else if(pid ==0)
    {
    printf("child process:pid=%d\n",getpid());
    //char * arg[]={"-a","-1","test_fork.c",NULL};
    execl("/bin/ls","-a","-1","test_fork.c",NULL);   
    execvp("ls",arg);
    perror("error exec\n");
    printf("child process:pid=%d\n",getpid());
    }  
    return 0;

}

 

wait函数

#include <sys/wait.h>
pid_t wait(int *status);


功能:挂起进程,进程进入阻塞状态,直到子进程变为僵尸态,如果捕获到子进程的退出信息就会转为运行态,然后回收子进程资源并返回;若没有变为僵尸态的子进程,wait函数就会让进程一直阻塞。若当前进程有多个子进程,只要捕获到一个变为僵尸态的子进程,wait函数就会恢复执行态。

参数说明:参数status是一个int *类型的指针,用来保存子进程退出时的状态信息。通常情况下该参数设为NULL,表示不关心进程时如何终止的。

 【案例一】 若子进程p1是其父进程p的先决进程,基于wait函数使得进程同步

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
    pid_t pid,w;
    pid=fork();
    if(pid ==-1)
    {
    perror("fork error");
    exit(1);
    }
    else if(pid>0)
    {
    w=wait(NULL);
    printf("Catched a child process,pid=%d\n",w);
    }
    else if(pid ==0)
    {
    sleep(3);
    printf("child process:pid=%d\n",getpid());
    }  
    return 0;
}

 

 

使用wait同步进程,并使用宏获取子进程的返回值。 

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
    int status;
    pid_t pid,w;
    pid=fork();
    if(pid ==-1)
    {
    perror("fork error");
    exit(1);
    }
    else if(pid>0)
    {
    w=wait(&status);
    if(WIFEXITED(status)){
    printf("Child process pid=%d exit normally.\n",w);
    printf("Return Code:%d\n",WEXITSTATUS(status));
        }
    else
        printf("Child process pid=%d exit abnormally.\n",w);
    }
    else if(pid ==0)
    {
    sleep(3);
    printf("child process:pid=%d\n",getpid());
    exit(5);
    }  
    return 0;
}

 

 

waitpid函数
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
功能:
wait函数的缺点:当前进程有很多个子进程,wait函数无法保证所有子进程在父进程之前执行。
waitpid函数:可以应对 wait函数面临的缺点。可以等待指定的子进程,也可以在父进程不阻塞的情况下获取子进程的状态。
参数说明:

pid:一般是进程的pid,也有可能是其他取值。进一步说明如下:
– pid > 0:等待子进程(编号为pid)退出,若退出,函数返回;若未结束,则一直等待;
– pid = 0:等待同一进程组的所有子进程退出,若某子进程加入了其他进程组,则waitpid不再关心它的状态;
– pid = -1:waitpid函数退化为wait函数,阻塞等待并回收一个子进程;
– pid < -1:等待指定进程组中的任何子进程,进程组的id等于pid的绝对值。
options: 提供控制选项,可以是一个常量,也可以是|连接的两个常量,选项如下:
– WNOHANG:如果子进程没有终止,waitpid不会阻塞父进程,会立即返回;
– WUNTRACED:如果子进程暂停执行,waitpid立即返回;
– 0:不使用选项。
返回值说明:
成功:返回捕捉到的子进程id;
0:options = WNOHANG, waitpid发现没有已退出的子进程可回收;
-1:出错,errno被设置。

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
    pid_t pid,p,w;
    pid=fork();
    if(pid ==-1)
    {
    perror("fork1 error");
    exit(1);
    }
    else if(pid ==0)
    {
    sleep(5);
    printf("First child process:pid=%d\n",getpid());
    }  
    else if(pid>0)
    {
    int i;
    p=pid;
    for(i=0;i<3;i++)
    {
        if((pid=fork())==0)
        break;
        }
    if(pid==-1)
    {
        perror("fork error");
        exit(2);
        }
    else if(pid==0)
    {
        printf("Child process:pid=%d\n",getpid());
        exit(0);
        }
    else if(pid>0)
    {
        w=waitpid(p,NULL,0);
        if(w==p)
        printf("Catch a child Process:pid=%d\n",w);
        else
        printf("waitpid error\n");
    }
    }
    return 0;
}

【案例 3】父进程等待进程组中指定子进程,该进程不退出,则父进程一直阻塞。 

 

 

【案例四】基于waitpid函数不断获取子进程的状态。 

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
    pid_t pid,w;
    pid=fork();
    if(pid ==-1)
    {
    perror("fork1 error");
    exit(1);
    }
    else if(pid ==0)
    {
    sleep(3);
    printf("child process:pid=%d\n",getpid());
    }  
    else if(pid>0)
    {
    do{
        w=waitpid(pid,NULL,WNOHANG);
        if(w==0){
        printf("No child exited\n");
        sleep(1);
        }
    }while(w==0);
    if(w==pid)
        printf("Catch a Child process:pid=%d\n",w);
     else
        printf("waited error\n");
    }
    return 0;
}

 小结

课上学习了进程创建fork,进程管理exec函数族,进程同步wait,waitpid等相关知识,通过五个案例对相关函数有了更深的体会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值