进程创建, 等待, 终止. 使用代码实现.

1.fork

pid_ t fork(void);
返回值:子进程返回0,父进程返回子进程的id,出错返回-1

当一个进程调用fork之后,就有两个二进制相同的进程。而且它们都运行到相同的地方。但每个进程都将开始它们自己的旅程。

  • 创建一个进程
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main( void )
{
    printf("before fork\n");

    pid_t pid = fork();

    if ( pid == 0 ) {
        //子进程
        while ( 1 ) 
            printf("child\n");
    } else if ( pid > 0 ) {
        //父进程
        while ( 1 )
            printf("parent\n");
    }else
    {
        //出错
        perror("fork");
        exit(1);
    }
}


  • 写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。
这里写图片描述

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int g_data = 250;

int main( void )
{
    pid_t pid = fork();

    if ( pid == 0 ) {
        g_data = 520;
        printf("child g_data = %p\n", &g_data);
        printf("child value  = %d\n", g_data);
    } else {
        sleep(1);
        printf("parent g_data = %p\n", &g_data);
        printf("parent value  = %d\n", g_data);
    }
}

这里写图片描述

  • fork调用失败的原因

    1.系统中有太多的进程
    2.实际用户的进程数超过了限制>

    2 .vfork函数

    • vork用于创建一个子进程,而子进程和父进程共享地址空间,fork的子进程具有独立地址空间
    • vork保证子进程先运行,在它调用exec或(exit)之后父进程才可能被调读运行

进程终止

  • 进程退出场景:

    • 代码运行完毕,结果正确
    • 代码运行完毕,结果不正确
    • 代码异常终止
  • 进程常见退出方法:
    正常终止:

    1.从main返回
    2.调用exit
    3._exit

异常退出:

ctrl + c ,信号终止

  • _exit函数:

    void _exit(int status);
    参数:status定义了进程的终止状态,父进程通过wait来获取该值
    说明:虽然status是int,但是仅有8为可以被父进程所用。所以_exit(-1)时,在中端执行行$?发现返回值是255。

  • exit函数:

    void exit(int status);

exit最后也会调用_exit,但在调用exit之前,还做了其他工作:

1.执行用户通过atexit或on_exit定义的清理函数
2.关闭所有打开的流,所有的缓存数据均被写入
3.调用exit

进程等待

  • wait:
#incldue<stdio.h>
#include<stdlib.h>

pid_t wait(int *status);

返回值:成功返回被等待进程pid,失败返回-1
参数:输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>

int main(void)
{
    pid_t pid = fork();

    if( pid == 1)
        perror("fork"),exit(EXIT_FAILURE);

    if (pid == 0)
    {
        sleep(20);
        printf("哈哈,我死了 pid = %d\n",getpid());
        exit(125);
    }
    else
    {
        int s;
        pid_t r = wait(&s);
        printf("r = %d\n",r);
        if (WIFEXITED(s))
        {
            printf("code = %d\n",WEXITSTATUS(s));
        }
    }
}


  • waitpid

pid_t waitpid(pid_t pid,int *status,int option);
返回值:
当正常返回的时候waitpid返回收集到的子进程的进程ID
如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在。
参数:
pid:
pid = -1,等待任一个子进程,与wait等效
pid > 0,等待其进程ID与pid相等的子进程
status:
WIFEXITED(status):若为正常终止子进程返回的状态,则为真。(查看进程是否正常退出)
WEXITSTATUS(status):若WIFDXITED非零,提取子进程退出码。(查看进程的退出码)
options:
WNOHANG:若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值