linux 父进程创建子进程的例子

linux 父进程创建子进程的例子,第1张

进程为什么要创建子进程呢?前面我们已经说过了Linux是一个多用户 *** 作系统,在同一时间会有许多的用户在争夺系统的资源.有时进程为了早一点完成任务就创建子进程来争夺资源. 一旦子进程被创建,父子进程一起从fork处继续执行,相互竞争系统的资源.有时候我们希望子进程继续执行,而父进程阻塞直到子进程完成任务.这个时候我们可以调用wait或者waitpid系统调用.

#i nclude

#i nclude

pid_t wait(int *stat_loc)

pid_t waitpid(pid_t pid,int *stat_loc,int options)

wait系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果没有父进程没有子进程或者他的子进程已经结束了wait回立即返回.成功时(因一个子进程结束)wait将返回子进程的ID,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态.子进程调用exit,_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值.

WIFEXITED:判断子进程退出值是非0

WEXITSTATUS:判断子进程的退出值(当子进程退出时非0).

WIFSIGNALED:子进程由于有没有获得的信号而退出.

WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义).

waitpid等待指定的子进程直到子进程返回.如果pid为正值则等待指定的进程(pid).如果为0则等待任何一个组ID和调用者的组ID相同的进程.为-1时等同于wait调用.小于-1时等待任何一个组ID等于pid绝对值的进程. stat_loc和wait的意义一样. options可以决定父进程的状态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到.

父进程创建子进程后,子进程一般要执行不同的程序.为了调用系统程序,我们可以使用系统调用exec族调用.exec族调用有着5个函数.

#i nclude

int execl(const char *path,const char *arg,…)

int execlp(const char *file,const char *arg,…)

int execle(const char *path,const char *arg,…)

int execv(const char *path,char *const argv[])

int execvp(const char *file,char *const argv[]):

exec族调用可以执行给定程序.关于exec族调用的详细解说可以参考系统手册(man execl). 下面我们来学习一个实例.注意编译的时候要加 -lm以便连接数学函数库.

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

void main(void)

{

pid_t child

int status

printf(”This will demostrate how to get child status\n”)

if((child=fork())==-1)

{

printf(”Fork Error :%s\n”,strerror(errno))

exit(1)

}

else if(child==0)

{

int i

printf(”I am the child:%ld\n”,getpid())

for(i=0i<1000000i++) sin(i)

i=5

printf(”I exit with %d\n”,i)

exit(i)

}

while(((child=wait(&status))==-1)&(errno==EINTR))

if(child==-1)

printf(”Wait Error:%s\n”,strerror(errno))

else if(!status)

printf(”Child %ld terminated normally return status is zero\n”,

child)

else if(WIFEXITED(status))

printf(”Child %ld terminated normally return status is %d\n”,

child,WEXITSTATUS(status))

else if(WIFSIGNALED(status))

printf(”Child %ld terminated due to signal %d znot caught\n”,

child,WTERMSIG(status))

}

strerror函数会返回一个指定的错误号的错误信息的字符串.

运维

Linux系统进程控制

行者111111111111111

原创

关注

0点赞·3人阅读

1、进程创建

shell命令行启动程序指令皆是创建了进程,我们通常通过调用fork()函数创建子进程。

1.1、fork()函数用法简介

调用fork后, *** 作系统内核将:

分配新的内存块和内核数据结构给子进程

将父进程部分数据结构内容拷贝至子进程

添加子进程到系统进程列表当中

fork返回,开始调度器调度

1.2、fork函数返回值

子进程返回0,父进程返回的是子进程的pid

原因:fork之后进入内核,申请内存构建子进程PCB、虚拟内存、页表,将子进程设置R状态,放入调度队列,由于创建子进程之后父子进程共享代码,所以父子进程都会有return返回值。返回值返回给变量本质发生了写时拷贝,改变了子进程对应页表的指向,数据映射到了其他区域

1.3、写时拷贝

由于进程要独立,代码不可修改,数据可改,所以默认数据各有一份,但是内存是有限度的,如果把父进程数据全部再拷贝一份,那么太浪费内存,甚至导致fork失败。通常通过写时拷贝实现,就是当父或子进程修改数据时,将要修改的数据拷贝一份,让子进程页表指向新的重复数据在发生修改

#include <unistd.h>

#include <stdio.h>

void child_process()

{

    while (true)

    {

        printf("I am child process\n")

    }

}

int main()

{

     pid_t pid = fork()

     if (pid < 0)

     {

         printf("fork error! exit\n")

     }   

     if (pid == 0) //子进程

     {

         child_process()

         return 0

     }   

     else //父进程

     {

         //父进程要执行的内容

     }

     return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8575975.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-18
下一篇 2023-04-18

发表评论

登录后才能评论

评论列表(0条)

保存