第26天进程(一)

目录

进程概念

查看进程

进程的特点(理解)

进程的资源分配(理解)

进程的状态(记住)

进程管理--PID

进程间关系(重点)

函数名:getpid()

函数名:getppid()

创建进程

函数名:fork() 

 函数名:vfork()

结束进程

函数名:_exit()

函数名:exit()

特殊进程

等待进程

函数名:wait()

函数名:waitpid()


进程概念

运行状态下的(硬盘中存储)程序(静态)----(内存中运行)进程(动态)

查看进程

Windows 任务管理器

2.2.2 Linux 终端指令

top #动态监控
ps -ef #显示系统中所有进程的详细信息

进程的特点(理解)

动态性:进程的实质是一次程序运行的过程,进程是动态产生、动态消亡的。

并发性:任何进程都可以和其他进程一起并发执行

独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的基本单位

异步性:进程的执行具有间断性,多个进程间按照各自独立的不可预知的速度向下运行

进程的资源分配(理解)

系统会给每个进程开辟 4G 的虚拟内存( =3G 用户内存+1G 的内核内存)

----当物理内存中的数据需要参与时,便加载到4G的虚拟内存中

  • 操作系统在为进程分配内存空间时,将其划分为堆、栈、数据段、未初始化数据段和文本段这五大区域。以达到基于内存管理和程序运行时数据组织有效划分的目的。

堆:手动开辟

栈:局部变量

数据段:全局变量和静态变量

                未初始化数据段:默认值为 0

                初始化数据段:会初始化设置的初始值

文本段:常量和代码

进程的状态(记住)

执行态:进程正在占用 CPU(CPU 正在执行该进程)

就绪态:进程已经满足本 CPU 分配时间片的条件(可以被 CPU 执行),在等待 CPU 给他分配时间片

等待态:进程没有满足被 CPU 分配时间片的条件,需要等到条件满足 CPU 才会给它分配时间片

进程管理--PID

一般情况下都是通过进程的 PID 号来操作进程

进程间关系(重点)

父子关系:进程 2 是由进程 1 创建的,那么进程 1 就是进程 2 的父进程,进程 2 就是进程 1 的子进程。 进程间有且只有父子关系

函数名:getpid()

头文件:

#include <sys/types.h>

#include <unistd.h>

函数原型:pid_t getpid(void);

函数功能:获取进程 pid

函数参数:无

函数返回值:返回 PID 号

函数使用:

#include <sys/types.h>
#include <unistd.h>
int main(){
    pid_t pid = getpid();
    printf("pid=%d\n",pid);
    sleep(10);//拉长时间,验证
    return 0;
}

 查找进程,验证。可以使用

ps -ef | grep "./a.out"

函数名:getppid()

头文件:

#include <sys/types.h>

#include <unistd.h>

函数原型:pid_t getppid(void);

函数功能:获取父进程 pid

函数参数:无

函数返回值:获取的 PPID

函数使用:

#include <sys/types.h>
#include <unistd.h>
int main(){
    pid_t ppid = getppid();
    printf("ppid=%d\n",ppid);
    sleep(10);//拉长时间,验证
    return 0;
}

创建进程

方法一:直接运行可执行程序

方法二:在程序中去调用进程创建函数去创建进程--fork、vfork。

函数名:fork() 

子进程复制父进程资源,然后和父进程从同一位置向下运行,执行的先后关系不确定

头文件:

#include<sys/types.h>

#include<unistd.h>

函数原型:pid_t fork(void);

函数功能:创建子进程

函数参数:无

函数返回值:-1 代表子进程创建失败,0 代表子进程,大于 0 代表父进程

函数使用:

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
int main(){
    pid_t pid =0;
    pid= fork();
    if(pid<0){
        perror("fork");
        return 0;
    }
    else if(pid==0){
        printf("pid=%d\n",getpid());
        printf("ppid=%d\n",getppid());
    }else{

        printf("this pid=%d\n",getpid());
    }
    return 0;
}

 函数名:vfork()

子进程占用父进程资源,然后子进程先使用资源执行,子进程结束后,父进程才能使用资源

头文件:

#include<sys/types.h>

#include<unistd.h>

函数原型:pid_t vfork(void);

函数功能:创建子进程,返回子进程 PID

函数参数:无

函数返回值:父进程返回子进程 PID 子进程返回 0

函数使用:

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main(){
    pid_t pid;  // 定义进程 ID 变量

    pid = vfork();  // 创建子进程,并获取子进程的进程 ID

    if(pid<0){  // 如果创建子进程失败
        perror("vfork");  // 打印错误信息
        return 1;  // 程序返回 1 并结束
    }else if(pid==0){  // 如果是子进程
        printf("pid=%d ",pid);  // 打印子进程的进程 ID
        printf("子进程先执行\n");  // 输出提示信息
        sleep(2);  // 子进程暂停 2 秒
        _exit(0);  // 子进程退出
    }else{  // 如果是父进程
        printf("pid=%d ",pid);  // 打印子进程的进程 ID
        printf("父进程等待子进程结束\n");  // 输出提示信息
        sleep(4);  // 父进程暂停 4 秒
    }
    return 0;  // 程序正常结束返回 0
}

当 vfork 被调用时,确实创建了一个新的子进程。在父进程中,pid 存储了新创建子进程的进程 ID(非 0 值),然后执行父进程中对应的代码块(第三个代码块)。

而在新创建的子进程中,pid 的值为 0 ,子进程执行第二个代码块。

需要注意的是,vfork 会让子进程先运行,并且子进程要尽快使用 exec 系列函数或 _exit 函数,,因为子进程和父进程共享地址空间。

结束进程

方法一:外部信号

在终端 ctrl+c 可以结束进程

在终端输入:kill -9 PID 可以结束进程

方法二:内部程序

1. main()中调用 return

2. 进程退出函数---exit()、_exit()

函数名:_exit()

头文件:#include<unistd.h>

函数原型:void _exit(int status);

函数功能:退出进程,不清空缓冲区

函数参数:获取进程退出时的状态 一般填 0

函数返回值:无

函数使用:

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

void write_to_buffer() {
    printf("This is written to the buffer.");
}
int main() {
    write_to_buffer();
    _exit(0);
    return 0;
}

函数名:exit()

头文件:#include

函数原型:void exit(int status);

函数功能:退出进程,清空缓冲区

函数参数:获取进程退出时的状态 一般填 0

函数返回值:无

函数使用:

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
void _EXIT_();
int main(){
    pid_t pid =0;
    pid= fork();
    if(pid<0){
        perror("fork");
        return 0;
    }
    else if(pid==0){
         sleep(3);
        printf("B");
       _EXIT_();
       printf("5678\n");
        
    }else{
         sleep(8);
        printf("A");
        exit(0);
    }
    return 0;
}
void _EXIT_(){
    exit(0);
    //return ;//5678
    printf("1234\n");
}

特殊进程


 0 号进程:操作系统启动的引导程序 祖先进程

1 号进程:操作系统启动的第一个程序


  • 孤儿进程: 父进程死了,子进程还在运行。孤儿进程会被系统中设置好的一个进程收养,并且等孤儿进程 死了之后给它收尸
  • 僵尸进程: 子进程死了,父进程没有给自己成收尸。这个时候子进程就会变成一个僵尸进程,僵尸进程所 占用的资源基本上会被完全释放,除了它所占用的进程号。父进程在退出之前,一定会给所有的僵尸进程收 尸。但是有些工程中的父进程需要长时间不停机运行,会导致僵尸进程的资源无法得到及时的回收处理。所以 咱们在编写代码的过程中,一定要尽量避免僵尸进程的产生。 可以通过在父进程中调用,下面的进程的等待函数来避免僵尸进程的产生。

等待进程

函数名:wait()

头文件:

#include<sys/types.h> 

#include<sys/wait.h>

函数原型:pid_t wait(int *wstatus);

函数功能:阻塞等待任意子进程结束

函数参数:进程结束状态 一般填 NULL

函数返回值:返回结束的子进程 pid

函数使用:

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

int main() {
    pid_t pid;
    pid = fork();  // 创建子进程
    if (pid < 0) {  // 子进程创建失败
        perror("Fork failed");
        return 1;
    } else if (pid == 0) {  // 子进程
        printf("I'm the child process!\n");
        sleep(3);  // 子进程暂停 3 秒
        _exit(0);  // 子进程退出
    } else {  // 父进程
        int status;
        pid_t child_pid = wait(&status);  // 父进程等待子进程结束
        if (child_pid == -1) {  // 等待失败
            perror("Wait failed");
            return 1;
        }
        printf("Child process %d exited. Status: %d\n", child_pid, status);
    }
    return 0;
}

这时候,我有一个问题:fork+wait=vfork?

答案:不对,fork + wait 并不等同于 vfork 。

fork 会创建一个新进程,子进程拥有父进程的完整副本,包括数据空间、堆、栈等。父进程和子进程可以并发执行。

vfork 创建的子进程会直接使用父进程的地址空间,并且子进程必须尽快调用 exec 系列函数或者 _exit 函数来替换当前进程的地址空间或者退出,否则可能会导致错误。

wait 函数用于父进程等待子进程结束并获取子进程的状态。

vfork 虽然也是创建子进程,但它与 fork 的行为有很大的不同,不能简单地认为 fork 加上 wait 就等于 vfork 。

函数名:waitpid()

头文件:

#include<sys/types.h> 

#include<sys/wait.h>

函数原型:pid_t waitpid(pid_t pid, int *wstatus, int options);

函数功能:等待子进程结束

函数参数:

  • pid

    • 负数:表示等待进程组 ID 等于该负数绝对值的任意子进程。
    • 0:等待当前进程组中的任意子进程。
    • 正数:等待指定进程 ID 的子进程。
  • wstatus:这是一个整数指针,用于接收子进程的退出状态信息。通过对这个状态值的解析,可以获取子进程退出的原因、是否正常退出等详细信息。通常,如果您不关心具体的状态细节,可以将其设置为 NULL

  • options:这是一个位掩码,用于控制 waitpid 的行为。

    • WNOHANG:表示非阻塞等待。如果没有子进程结束,函数会立即返回 0 ,而不会阻塞。
    • 0:表示阻塞等待,直到指定的子进程结束。

函数返回值:

  • 如果成功等待到指定子进程结束,返回结束子进程的进程 ID 。
  • 如果设置了 WNOHANG 选项且没有子进程结束,返回 0 。
  • 如果出现错误,返回 -1 ,同时会设置 errno 来指示错误类型。

函数使用:

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

int main() {
    pid_t pid;
    pid = fork();  // 创建子进程
    if (pid < 0) {  // 子进程创建失败
        perror("Fork failed");
        return 1;
    } else if (pid == 0) {  // 子进程
        printf("I'm the child process!\n");
        sleep(3);  // 子进程暂停 3 秒
        _exit(0);  // 子进程退出
    } else {  // 父进程
        int status;

        // 阻塞等待指定子进程结束
        pid_t result = waitpid(pid, &status, 0);  
        if (result == -1) {
            perror("Waitpid failed");
            return 1;
        }
        printf("Child process %d exited. Status: %d\n", pid, status);

        // 非阻塞等待当前进程组中的任意子进程结束
        result = waitpid(-1, &status, WNOHANG);  
        if (result > 0) {
            printf("Another child process exited. PID: %d, Status: %d\n", result, status);
        } else if (result == 0) {
            printf("No child process exited yet.\n");
        } else {
            perror("Waitpid (WNOHANG) failed");
            return 1;
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/919524.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

天津渤海职业技术学院“讯方技术HarmonyOS人才训练营”圆满开展

5月6日-8日&#xff0c;讯方技术与天津渤海职业技术学院联合成功举办了一场技术盛宴——HarmonyOS人才训练营&#xff0c;吸引了学院网络专业的140余名学生踊跃参与。讯方技术专家帖莎娜作为本次训练营的讲师&#xff0c;为学生们提供了全面、深入的HarmonyOS操作系统技术讲解与…

OpenProject安装部署与使用介绍

OpenProject安装部署与使用介绍 1. OpenProject简介 1-1. 什么是OpenProject ​ OpenProject是一个功能全面的开源项目管理软件&#xff0c;它提供了一套集成的工具来支持项目规划、协作和监控。它的核心功能包括任务和问题跟踪、时间管理、新闻和文档管理&#xff0c;以及集…

标题gitLab如何打标签

标题gitLab打标签 1、首先进入到项目里面&#xff0c;找到Repository下的Tages&#xff0c;点击进入 如果是还没有创建过标签&#xff0c;会提示如何用命令创建 git tag -a v1.4 -m "version 1.4"2、也可以直接在界面创建&#xff0c;点击new Tag按钮 3、填写标签…

在centos7中安装SqlDeveloper的Oracle可视化工具

1.下载安装包 &#xff08;1&#xff09;在SqlDeveloper官网下载&#xff08;Oracle SQL Developer Release 19.2 - Get Started&#xff09;对应版本的安装包即可&#xff08;安装包和安装命令如下&#xff09;&#xff1a; &#xff08;2&#xff09;执行完上述命令后&#x…

【D3.js in Action 3 精译_040】4.4 D3 弧形图的绘制方法

当前内容所在位置&#xff1a; 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建&#xff08;上篇&#xff09; 4.1.1 D3 中的边距约定&#xff08;中篇&#xff09;4.1.2 坐标轴的生成&#xff08;中篇&#xff09; 4.1.2.1 比例尺的声明&#xff08;中篇&#xff09;4.1…

Flink监控checkpoint

Flink的web界面提供了一个选项卡来监控作业的检查点。这些统计信息在任务终止后也可用。有四个选项卡可以显示关于检查点的信息:概述(Overview)、历史(History)、摘要(Summary)和配置(Configuration)。下面依次来看这几个选项。 Overview Tab Overview选项卡列出了以…

跨平台WPF框架Avalonia教程 十五

ListBox 列表框 列表框从元素源集合中显示多行元素&#xff0c;并允许选择单个或多个。 列表中的元素可以组合、绑定和模板化。 列表的高度会扩展以适应所有元素&#xff0c;除非特别设置&#xff08;使用高度属性&#xff09;&#xff0c;或由容器控件设置&#xff0c;例如…

【Redis】Redis实现的消息队列

一、用list实现【这是数据类型所以支持持久化】 消息基于redis存储不会因为受jvm内存上限的限制&#xff0c;支持消息的有序性&#xff0c;基于redis的持久化机制&#xff0c;只支持单一消费者订阅&#xff0c;无法避免消息丢失。 二、用PubSub【这不是数据类型&#xff0c;是…

从0-1训练自己的数据集实现火焰检测

随着工业、建筑、交通等领域的快速发展,火灾作为一种常见的灾难性事件,对生命财产安全造成了严重威胁。为了提高火灾的预警能力,减少火灾损失,火焰检测技术应运而生,成为火灾监控和预防的有效手段之一。 传统的火灾检测方法,如烟雾探测器、温度传感器等,存在响应时间慢…

【vmware+ubuntu16.04】ROS学习_博物馆仿真克隆ROS-Academy-for-Beginners软件包处理依赖报错问题

首先安装git 进入终端&#xff0c;输入sudo apt-get install git 安装后&#xff0c;创建一个工作空间名为tutorial_ws&#xff0c; 输入 mkdir tutorial_ws#创建工作空间 cd tutorial_ws#进入 mkdir src cd src git clone https://github.com/DroidAITech/ROS-Academy-for-Be…

13. Linux上CUDA的安装

这个专栏记录我学习/科研过程中遇到的一些小问题以及解决方案&#xff0c;一些问题可能比较蠢请见谅。自用&#xff0c;仅供参考。 ------------------------------------------------------------------------------------ Linux上CUDA的安装 在安装之前&#xff0c;首先要确…

ThinkPHP6门面(Facade)

门面 门面&#xff08;Facade&#xff09; 门面为容器中的&#xff08;动态&#xff09;类提供了一个静态调用接口&#xff0c;相比于传统的静态方法调用&#xff0c; 带来了更好的可测试性和扩展性&#xff0c;你可以为任何的非静态类库定义一个facade类。 系统已经为大部分…

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现

博主可接毕设设计&#xff01;&#xff01;&#xff01; 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互…

[Admin] Dashboard Filter for Mix Report Types

Background RevOps team has built a dashboard for sales team to track team members’ performance, but they’re blocked by how to provide a manager view based on sales’ hierarchy. Therefore, they seek for dev team’s help to clear their blocker. From foll…

游戏引擎学习第19天

介绍 这段内容描述了开发者在进行游戏开发时&#xff0c;对于音频同步和平台层的理解和调整的过程。以下是更详细的复述&#xff1a; 开发者表达了他希望今天继续进行的工作内容。他提到&#xff0c;昨天他讲解了一些关于音频的内容&#xff0c;今天他想稍微深入讲解一下他正…

高阶云服务-ELB+AS

ELBAS 弹性负载均衡弹性伸缩 原来1台web服务器不满足相应&#xff0c;现部署多台提供相同服务&#xff1b; 由于多个服务器多个ip该如何提供给应用呢&#xff1f; 引申出负载均衡&#xff08;HAProxy&#xff0c;LVS01四层&#xff0c;Nginx七层&#xff09; 防单点故障做主备…

STM32设计防丢防摔智能行李箱-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 1.电路图采用Altium Designer进行设计&#xff1a; 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着科技的不断发展&#xff0c;嵌入式系统、物联网技术、智能设备…

Mysql中REPLACE INTO详解及和INSERT INTO的区别

前言 我们在进行数据库操作的时候&#xff0c;经常会遇到这样的场景&#xff1a; 首先判断数据是否存在&#xff1b;如果不存在&#xff0c;则插入&#xff1b;如果存在&#xff0c;则更新。 博主之前是是Java来进行逻辑判断&#xff0c;例如&#xff1a; 看起来似乎也很简洁…

基于Java Springboot发艺美发店管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

element ui 走马灯一页展示多个数据实现

element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 主要是对走马灯的数据的操作&#xff0c;先看js处理 let list [{ i: 1, name: 1 },{ i: 2, name: 2 },{ i: 3, name: 3 },{ i: 4, name: 4 },]let newL…