当前位置: 首页 > article >正文

Linux中的进程控制

目录

进程控制

fork函数初识

fork详解

写时拷贝

退出码

进程常见退出方法

exit/_exit

进程等待

wait方法

 waitpid

 代码实现

非阻塞式等待


进程控制

fork函数初识

fork详解

1.如何理解fork有两个返回值?

fork()函数执行后,存在父子两个执行流。所以会有两个返回值。

2.如何理解fork返回之后,给父进程返回子进程pid,给子进程返回0?

一个孩子只有一个父亲,所以子进程不需要父进程的id值。

一个父亲可以有多个孩子,故需要有pid标识具体是哪一个孩子。

3.如何理解同一个id值,会保存两个不同的值,让if  else if同时执行?

同一个id,地址是一样的但是内容却有可能不一样。

pid_t id=fork();

返回的本质就是写入,返回时会发生写时拷贝,谁先返回,谁就会先写入。(进程具有独立性)

写时拷贝

通常,父子代码共享,父子再不写入时,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副 本。具体见下图:

退出码

return 0;

0为进程退出时候对应的退出码,标定进程退出的结果是否正确。

./mytest

运行一个进程

echo $?

$?:永远记录最近一个进程在命令行中执行完毕时,对应的退出码。即main函数的返回值。

echo:自身的退出码为0.

Linux共提供了134个。

ls

ls使用c语言写的,Linux下一切皆文件。

进程常见退出方法

正常终止(可以通过 echo $? 查看进程退出码):

1. 从main返回

2. 调用exit

3. _exit

异常退出:

ctrl + c,信号终止

exit/_exit

exit: 终止进程,主动刷新缓冲区

_exit: 终止进程,不会刷新缓冲区

缓冲区--->是一个用户级缓存区。

进程等待

父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息(进程为什么要等待)

wait方法

#include<sys/types.h>
#include<sys/wait.h>
 
pid_t wait(int*status);
 
返回值:
 成功返回被等待进程pid,失败返回-1。
参数:
 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

 waitpid

#include<sys/types.h>
#include<sys/wait.h>
 
pid_t wait(int*status);
 
返回值:
 成功返回被等待进程pid,失败返回-1。
参数:
 输出型参数,获取子进程退出状态,不关心则可以设置成为NULL
pid_ t waitpid(pid_t pid, int *status, int options);

options为0,代表阻塞式等待。

通过status应体现出这三种状况:

代码运行完毕,结果正确

代码运行完毕,结果不正确

代码异常终止

status不是被整体使用的,status有自己的位图结构。

 代码实现

非阻塞式等待

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<unistd.h>
#include<sys/types.h> 
#include<sys/wait.h>
int main()
{
    pid_t id=fork();
    assert(id!=-1);
    if(id==0)
    {
        int cnt=10;
        while(cnt)
        {
            printf("child running,pid: %d, ppid: %d, cnt:%d\n",getpid(),getppid(),cnt);
            sleep(3);
        }
        exit(6);
    }
    int status =0;
    while (1)
    {
        //非阻塞式等待,父进程检测后立即返回
        pid_t ret=waitpid(id+1,&status,WNOHANG);
        if(ret==0)
        {
            //waitpid调用成功,子进程还未退出
            printf("wait done,but child is running.....\n");
        }
        else if(ret>0)
        {
            //waitpid调用成功,子进程退出
            printf("wait success,exit code: %d, sig: %d\n",(status>>8)&0xff,status&0x7f);
        }
        else
        {
            printf("waitpid call failed\n");
            break;
        }
    }
    return 0;
}

waitpid:检测子进程退出信息,将子进程退出信息(存在子进程的PCB中)通过status拿到。

status:

WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

options:

WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进 程的ID。


http://www.kler.cn/news/324953.html

相关文章:

  • 集成Elasticsearch到django restful
  • 使用【apifox】进行压测-保姆级教程【无需脚本】
  • Unity中分辨率适配
  • 一文上手SpringSecurity【九】
  • Kafka技术详解[1]:简介与基础概念
  • 基于springboot+vue+mysql公益旧物捐赠系统(源码+参考文档+定制)
  • pytorch U²-Net教程
  • NTLM Relay攻击原理 + 工具使用
  • 【SQL】累计统计方法,使用SQL详细写出
  • itc保伦股份智慧高校整体解决方案推动教育强国、科技强国、人才强国建设!
  • 【AI写代码】使用 ChatGPT 写 ila
  • [Unity Demo]从零开始制作空洞骑士Hollow Knight第十一集:制作法术系统的回血机制和火球机制
  • YOLO V8半自动标注工具设计
  • macOS 开发环境配置与应用开发
  • Selenium与数据库结合:数据爬取与存储的技术实践
  • 项目管理系统中的风险管理:如何识别和应对项目风险?
  • three.js----快速上手,如何用vue在web页面中导入 gltf/glb , fbx , obj 模型
  • JavaScript动态数据可视化
  • 微信小程序环境下的相亲交友系统源码优化
  • Java必修课——Spring框架
  • 深度学习:残差网络(ResNet)的原理及优缺点
  • OpenCV-图像透视变换
  • Web 3.0 介绍
  • Docker实践与应用举例
  • MPI程序实例:自适应数值积分
  • k8s中,pod生命周期,初始化容器,容器探针,事件处理函数,理解其设计思路及作用
  • 字段映射和数据转换为什么是数据集成的关键?
  • 数据结构:栈 及其应用
  • 汽车总线之---- LIN总线
  • 一文上手SpringSecurity【二】