进程的数据输入输出

进程参数和环境参数的意义

—  一般情况下,子进程的创建是为了解决某个子问题

—  子进程解决问题需要父进程的"数据输入" (进程参数 & 环境变量)

设置原则:

  • 子进程启动时必然用到的参数使用进程参数传递
  • 子进程解决问题可能用到的参数使用环境变量传递
编程示例:

      

可以看到需要返回值是19 注意echo $?是打印最近一个进程的执行结果!!!


深入理解父子进程

—  子进程的创建是为了并行的解决子问题(问题分解)
—  父进程需要通过子进程的结果最终解决问题(并获取结果)

进程等待系统接口

pid_t wait(int* status)   标准

  • 等待一个子进程完成,并返回子进程标识和状态信息
  • 当有多个子进程完成,随机挑选一个子进程返回

pid_t waitpid(pid_t pid, int* status, int options);  maxpro

  • 可等待特定的子进程或一组子进程
  • 在子进程还未终止时,可通过options设置不必等待(直接返回)

进行退出系统接口

  • 头文件:#include <unistd.h>
  • void _exit(int status); //系统调用,终止当前进程
  • 头文件:#include <stdlib.h>
  • void exit(int status);  //库函数,先做资清理,再通过系统调用终止进程
  • void abort(void);       //异常终止当前进程(通过产生SIGABRT信号终止)

僵尸进程

  • 理论上,进程 退出/终止 后应立即释放所有系统资源
  • 然而,为了给父进程提供一些重要信息,子进程 退出/终止 所占的部分资源会暂留
  • 当父进程收集这部分信息后(wait/waitpid),子进程所有资源被释放
    • 父进程调用 wait(),为子进程"收尸"处理并释放暂留资源
    • 若父进程退出,init/systemd 为子进程"收尸"处理并释放暂留资源

僵尸进程的危害

  • 僵尸进程保留进程的 终止状态 和 资源的使用信息
    • 进程为何退出,进程消耗CPU时间,进程最大内存驻留值,等
  • 如果僵尸进程得不到回收,那么可能影响正常进程的创建
    • 进程创建最重要的资源是内存和进程标识
    • 僵尸进程的存在可看作一种类型的内存泄漏
    • 当系统僵尸进程过多,可能导致进程标识不足,无法创建新进程

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

static void worker(pid_t pid)
{
    printf("grand-child: %d\n", pid);
    sleep(150);
}

int main(int argc, char* argv[])
{   
    pid_t pid = 0;
    int status = 0;
    
    printf("parent = %d\n", getpid());
    
    pid = fork();
    
    if( pid < 0 )
    {
        printf("fork error\n");
    }
    else if( pid == 0 )
    {
        int i = 0;
        
        for(i=0; i<5; i++)
        {
            if( (pid = fork()) == 0 )
            {
                worker(getpid());
                break;
            }
        }
        
        sleep(60);
        
        printf("child(%d) is over...\n", getpid());
    }
    else
    {
        printf("wait child = %d\n", pid);     
        sleep(120);
        while( waitpid(pid, &status, 0) == pid )
        {
            printf("Parent is over - child: %d, status = %x\n", pid, status);
        }
    }
    
    return 0;
}

可能用到命令

gcc test.c

./a.out &

ps ax |grep pts

僵尸进程避坑指南

利用 wat(...) 返回值判断是否继续等待子进程
while((pid = wait(&status)) > 0 ) {...}
利用 waitpid(...) 及 init /systemd 回收子进程
通过两次fork() 创建孙进程解决子问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值