linux学习(进程管理)[8]

news2025/1/13 13:16:51

创建进程

myproc.c

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

int main()
{
	printf("我是父进程\n");
	
	pid_t id = fork();
	if(id < 0)
	{
		printf("创建子进程失败\n");
		return 1;
	}
	else if(id == 0)
	{
		while(1)
		{
			printf("我是子进程: pid: %d ,ppid: %d\n",getpid(),getppid());
			sleep(1);
		}
	}
	else
	{
		while(1)
		{
			printf("我是父进程: pid: %d ,ppid: %d\n",getpid(),getppid());
			sleep(1);
		}
 	}
}

子进程0,父进程1,失败-1
在这里插入图片描述
查看进程

ps axj | grep myproc

描述,fork创建子进程时,操作系统都做了什么

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
fork之后子进程和父进程共享全部代码,而不仅仅只有after后的

写时拷贝

在Linux中,fork()系统调用用于创建一个新的进程,新进程是原始进程(父进程)的副本。在fork()调用之后,父进程和子进程共享相同的内存映像,这包括代码段、数据段和堆栈。

在fork()调用之后,父进程和子进程之间使用写时拷贝(Copy-on-Write,COW)技术来减少内存开销。具体来说,当父进程或子进程尝试修改共享的内存页时,操作系统会为修改后的内存页创建一个新的副本,并使父进程和子进程指向各自的副本。

下面是一个示例,演示了父子进程的写时拷贝:

#include <iostream>
#include <unistd.h>

int main() {
    int data = 100;

    pid_t pid = fork();

    if (pid == -1) {
        std::cerr << "fork() failed" << std::endl;
        return 1;
    } else if (pid == 0) {
        // 子进程
        std::cout << "Child process: data = " << data << std::endl;
        data = 200;
        std::cout << "Child process: modified data = " << data << std::endl;
    } else {
        // 父进程
        std::cout << "Parent process: data = " << data << std::endl;
        data = 300;
        std::cout << "Parent process: modified data = " << data << std::endl;
    }

    return 0;
}

在上述代码中,我们首先定义了一个整数变量data,并初始化为100。然后,我们调用fork()系统调用创建一个新的进程。

在子进程中,我们输出data的值,然后将其修改为200,并再次输出修改后的值。

在父进程中,我们也输出data的值,然后将其修改为300,并再次输出修改后的值。

运行上述代码,可能会得到如下输出:

Parent process: data = 100
Parent process: modified data = 300
Child process: data = 100
Child process: modified data = 200

可以看到,父子进程共享相同的data变量,但在修改时会进行写时拷贝,使得父进程和子进程拥有各自的副本。因此,父进程和子进程对data变量的修改互不影响。
延时申请技术
创建子进程,不需要将不会被访问的,或者只会读取的数据拷贝一份将来会被父进程或者子进程写入的数据才会拷贝但是一般而言os无法提前知道哪些空间可能会被写入,即使拷贝也不知拷贝时间
==所以os使用写时拷贝技术将父子进程的数据进行分离 ==
在这里插入图片描述

cpu怎么知道要执行什么指令||子进程为什么从after后执行

在这里插入图片描述

进程终止

  1. 操作系统所作:
    操作系统释放进程申请相关的内核数据结构和对应的数据和代码本质就是释放系统资源

  2. 进程终止的常见方式:
    a. 代码跑完,结果正确
    b.代码跑完,结果不正确 (main函数返回值的意义?return0 ?)
    c.代码没有跑完,程序崩溃了(信号部分)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 用代码如何终止一个进程
    main函数的return语句就是用来终止进程的! return+退出码
    exit在代码的任何地方调用,都表示直接终止进程
    exit在退出时会将数据刷新到缓冲区 _exit不会

exit || _exit

在这里插入图片描述
在这里插入图片描述

进程等待

在这里插入图片描述
父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息

wait–基本验证,回收僵尸进程的问题

在这里插入图片描述
阻塞式等待
在Linux中,wait()waitpid()是用于进程等待的系统调用。

wait()系统调用用于让父进程等待其子进程的终止。当父进程调用wait()时,如果子进程已经终止,则wait()立即返回,并返回子进程的进程ID。如果子进程还未终止,则父进程会被阻塞,直到子进程终止。

waitpid()系统调用是wait()的一个变种,它允许父进程指定要等待的子进程的进程ID。此外,waitpid()还可以指定一些额外的选项,例如WNOHANG,使waitpid()在没有可等待的子进程时立即返回。

下面是一个示例,演示了wait()waitpid()的使用:

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

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

    if (pid == -1) {
        std::cerr << "fork() failed" << std::endl;
        return 1;
    } else if (pid == 0) {
        // 子进程
        std::cout << "Child process: PID = " << getpid() << std::endl;
        sleep(2); // 子进程休眠2秒
        std::cout << "Child process: exiting" << std::endl;
        return 0;
    } else {
        // 父进程
        std::cout << "Parent process: PID = " << getpid() << std::endl;
        std::cout << "Parent process: waiting for child process to exit" << std::endl;

        // 等待子进程终止
        int status;
        pid_t terminated_pid = wait(&status);

        if (WIFEXITED(status)) {
            std::cout << "Parent process: child process " << terminated_pid << " exited normally with status " << WEXITSTATUS(status) << std::endl;
        } else if (WIFSIGNALED(status)) {
            std::cout << "Parent process: child process " << terminated_pid << " exited due to signal " << WTERMSIG(status) << std::endl;
        }
    }

    return 0;
}

在上述代码中,我们使用fork()创建了一个子进程。在子进程中,我们输出子进程的进程ID,然后休眠2秒钟,最后返回0。

在父进程中,我们输出父进程的进程ID,并使用wait()等待子进程终止。当子进程终止后,wait()返回子进程的进程ID,并将子进程的状态存储在status变量中。我们使用WIFEXITED()WEXITSTATUS()宏来检查子进程是否正常终止,并获取子进程的退出状态。

运行上述代码,可能会得到如下输出:

Parent process: PID = 1234
Parent process: waiting for child process to exit
Child process: PID = 1235
Child process: exiting
Parent process: child process 1235 exited normally with status 0

可以看到,父进程调用wait()等待子进程终止,并成功获取到子进程的退出状态。
在上述代码中,status是一个整数变量,用于存储子进程的终止状态。在wait()waitpid()返回时,可以通过检查status来获取子进程的退出状态。

status的类型是int,但它实际上是一个位字段,可以通过一些宏来解析它的值。下面是一些常用的宏:

  • WIFEXITED(status):如果子进程正常终止,则返回真。
  • WEXITSTATUS(status):如果WIFEXITED()为真,则返回子进程的退出状态。
  • WIFSIGNALED(status):如果子进程因为信号而终止,则返回真。
  • WTERMSIG(status):如果WIFSIGNALED()为真,则返回导致子进程终止的信号编号。

这些宏可以帮助我们解析status变量,以确定子进程的终止状态。

在上述示例代码中,我们使用了WIFEXITED()WEXITSTATUS()宏来检查子进程是否正常终止,并获取子进程的退出状态。如果子进程正常终止,WEXITSTATUS()将返回子进程的退出状态。

如果子进程因为信号而终止,我们可以使用WIFSIGNALED()WTERMSIG()宏来获取导致子进程终止的信号编号。

请注意,status中的位字段是由操作系统设置的,因此可以使用这些宏来解析status的值。

waitpid–获取子进程退出结果的问题

在这里插入图片描述
status不是按照整数来体现的
在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

7.利用matlab完成 符号方阵的特征值分解和 符号矩阵的奇异值分解 (matlab程序)

1.简述 &#xff08;1&#xff09;特征值分解&#xff1a;函数eig 格式&#xff1a;[V,D] eig(A) %计算A的特征值对角阵D和特征向量V&#xff0c;使AVVD成立。 注意&#xff1a;特征值分解时&#xff0c;使用eig&#xff0c;矩阵A必须是方阵。 A [0 1;1 1]; [V,D] ei…

JAVA初体验 (HelloWorld)

1.编写代码 文件名字HelloWorld.java public class HelloWorld{public static void main(String [] args){System.out.printf("hello world!");} } 2.编译&#xff08;cmd&#xff09; javac HelloWorld.java 运行完之后 会出现一个 HelloWorld.class 3.运行 j…

APS生产排产将排程计划可视化

什么是生产计划可视化&#xff1f; 在制定生产计划时&#xff0c;由于是多工序的生产&#xff0c;物料及设备的匹配&#xff0c;生产工艺路线的安排&#xff0c;产品结构的不同等因素&#xff0c;生产计划的排程有一定的难度。 那么如何将一个复杂的生产计划转化为一张清晰明了…

Python分享之 Spider

一、网络爬虫 网络爬虫又被称为网络蜘蛛&#xff0c;我们可以把互联网想象成一个蜘蛛网&#xff0c;每一个网站都是一个节点&#xff0c;我们可以使用一只蜘蛛去各个网页抓取我们想要的资源。举一个最简单的例子&#xff0c;你在百度和谷歌中输入‘Python&#xff0c;会有大量和…

Python(三)

诚信像一面镜子&#xff0c;一旦打破&#xff0c;你的人格就会出现裂痕。 存在短路的情景 谢谢观看 Python(三)

造个破谣而已,咋还用上AI了?

最近&#xff0c;央视等各大媒体纷纷曝光了全国多起用AI炮制网络谣言的案例&#xff0c;其中涉及灾害、安全事故、刑事案件等多类谣言内容&#xff0c;造谣的方式更是从文案到图片、视频不一而足。 看到这样的消息&#xff0c;总是会加重我们对AI的担忧&#xff0c;联想到此前的…

承接各种设计

小弟985研究生毕业&#xff0c;目前攻读读博士&#xff0c;可做各种设计&#xff0c;包括但不限于Matlab 电力电子/电气工程&#xff0c;matlab/simulink 电气专业仿真MATLAB 电气工程专业&#xff0c;matlab建模 电力电子&#xff0c;电气工程&#xff0c;电力系统&#xff0c…

Vision Transformer模型入门

Vision Transformer模型入门 一、Vision Transformer 模型1&#xff0c;Embedding 层结构详解2&#xff0c;Transformer Encoder 详解3&#xff0c;MLP Head 详解 二、ViT-B/16 网络结构三、Hybrid 模型详解四、ViT 模型搭建参数 一、Vision Transformer 模型 总体三个模块&am…

第三节:在WORD为应用主窗口下关闭EXCEL的操作(1)

【分享成果&#xff0c;随喜正能量】夏日里的遗憾&#xff0c;一定都会被秋风温柔化解。吃素不难&#xff0c;难于不肯捨贪口腹之心。若不贪口腹&#xff0c;有何吃素之不便乎。虽吃华素&#xff0c;不吃素日&#xff0c;亦须少吃。以一切物类&#xff0c;皆是贪生怕死&#xf…

Java并发编程(四)线程同步 中 [AQS/Lock]

概述 Java中可以通过加锁&#xff0c;来保证多个线程访问某一个公共资源时&#xff0c;资源的访问安全性。Java提出了两种方式来加锁 第一种是我们上文提到的通过关键字synchronized加锁&#xff0c;synchronized底层托管给JVM执行的&#xff0c;并且在java 1.6 以后做了很多…

stringstream常见用法

目录 构造函数 输出字符串 修改和清空字符串 利用 stringstream 去除字符串空格 利用stringstream去除指定的字符 stringstream 数据库 <sstream> 构造函数 创建一个对象&#xff0c;向对象输入字符串&#xff1a; string x"abcdefg";stringstream s…

运维监控学习笔记1

1、监控对象&#xff1a; 1、监控对象的理解&#xff1b;CPU是怎么工作的&#xff1b; 2、监控对象的指标&#xff1a;CPU使用率&#xff1b;上下文切换&#xff1b; 3、确定性能基准线&#xff1a;CPU负载多少才算高&#xff1b; 2、监控范围&#xff1a; 1、硬件监控&#x…

选择最适合自己的笔记本

选择最适合自己的笔记本电脑 一、了解笔记本品牌一线品牌准一线品牌二线品牌三线品牌 二、笔记本入手渠道笔记本入手渠道 三、根据需求选择机型使用需求1.日常使用2.商务办公、财务3.轻度剪辑、ps4.代码5.创意设计6.游戏 四、笔记本电脑配置如何选1.cpu2.显卡&#xff08;GPU&a…

在x86下运行的Ubuntu系统上部署QEMU用于模拟RISC-V硬件环境

1.配置工作环境 sudo apt install gcc bison flex libncurses-dev ninja-build \pkg-config build-essential zlib1g-dev pkg-config libglib2.0-dev \binutils-dev libboost-all-dev autoconf libtool libssl-dev \libpixman-1-dev python-capstone virtualenv software-prop…

第三章 图论 No.10无向图的双连通分量

文章目录 定义Tarjan求e-DCCTarjan求v-DCC395. 冗余路径1183. 电力396. 矿场搭建 定义 无向图有两种双连通分量 边双连通分量&#xff0c;e-DCC点双连通分量&#xff0c;v-DCC 桥&#xff1a;删除这条无向边后&#xff0c;图变得不连通&#xff0c;这条边被称为桥 边双连通分…

(文章复现)基于灰狼算法(GWO)的交直流混合微网经济调度matlab代码

参考文献&#xff1a; [1]高瑜,黄森,陈刘鑫等.基于改进灰狼算法的并网交流微电网经济优化调度[J].科学技术与工程, 2020,20(28):11605-11611. [2]邓长征,冯朕,邱立等.基于混沌灰狼算法的交直流混合微网经济调度[J].电测与仪表, 2020, 57(04):99-107. 这两篇文章不管是从模型、…

【JavaScript】new 的原理以及实现

网道 - new 命令的原理 使用new命令时&#xff0c;它后面的函数依次执行下面的步骤。 创建一个空对象&#xff0c;作为将要返回的对象实例。将这个空对象的原型&#xff0c;指向构造函数的prototype属性。将这个空对象赋值给函数内部的this关键字。如果构造函数返回了一个对象…

[内网渗透]CFS三层靶机渗透

文章目录 [内网渗透]CFS三层靶机渗透网络拓扑图靶机搭建Target10x01.nmap主机探活0x02.端口扫描0x03.ThinkPHP5 RCE漏洞拿shell0x04.上传msf后门(reverse_tcp)反向连接拿主机权限 内网渗透Target2&#xff08;1&#xff09;路由信息探测&#xff08;2&#xff09;msf代理配置&a…

Air001基于Keil环境点灯和调试输出工程配置

Air001基于Keil环境点灯和调试输出工程配置 &#x1f4cc;官方环境搭建教程介绍&#xff1a;https://wiki.luatos.com/chips/air001/Air001-MDK.html&#x1f516;本人使用的是基于HAL库环境搭建的。&#x1f4cd;SDK开发资源链接&#xff1a;https://gitee.com/openLuat/luato…

私域流量宝工具源码搭建-含详细使用说明

&#x1f44b;私域流量宝致力于为个人、团队提供基于微信私域流量的推广、引流的效率工具。可减轻人力&#xff0c;有效降低资源损失、流量流失的几率。引流宝完全开源&#xff0c;免费&#xff0c;可商用、可任意二次开发。引流宝可以辅助你更好地开展营销活动推广&#xff01…