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

【Linux】进程控制1——进程创建和进程终止

1.进程创建

1.1.再谈fork

在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。

#include <unistd.h>
pid_t fork(void);//pid_t为整形 

返回值:子进程中的fork()返回0,父进程中的fork()返回子进程的id (pid),出错时返回 -1 

在前面创建子进程的时候就学过了fork函数,它能从已经存在进程中创建一个新进程,新进程为子进程,而原进程为父进程。

        当进程调用fork,当控制转移到内核中的fork代码后,内核做:

 pid_t fork(void)

{

  • 1.分配新的内存块和内核数据结构给子进程
  • 2.将父进程部分数据结构内容拷贝至子进程
  • 3.添加子进程到系统进程列表当中
  • 4.fork返回,开始调度器调度

}

 fork之前父进程独立执行,fork之后,父子两个执行流分别执行。注意,fork之后,谁先执行完全由调度器决定。

子进程的特点:

        1.将父进程的所有数据共享或拷贝 到了子进程中。(若子进程不对父进程的数据进行修改的话,父子进程的数据也是共享的。若子进程对父进程的数据进行修改时,会发生写时拷贝,将父进程的数据进行拷贝一份到子进程中)

写时拷贝 :(是一种延时申请技术,可以提高整机内存的使用率)

        2.子进程和父进程的所有代码共享

        3.由于 程序计数器 和   CPU中存储上下文数据的寄存器 原因,子进程虽然可以共享父进程的所有代码,但是在子进程中是从fork()创建子进程之后的代码开始执行的,fork()创建子进程之前的代码默认已经执行过,不会重复执行,所以子进程会执行子进程创建之后的代码。但是由于fork()进行返回值是在子进程创建之后进行返回的,所以子进程依然会执行fork()的返回值。

我们之前详细讲过fork函数,就不再讨论fork函数了

1.2.创建进程

使用fork函数创建子进程

2.进程退出 

2.1. 退出码

通常main函数最后都要有一句return 0,这些数字有什么意义吗?

int main()
{//...return 0;
}

 我们可以来看看

#include<stdio.h>                                                                                                            
#include<string.h>                                                                                                           int AddtoTarget(int from,int end)                                                                                            
{                                                                                                                            int sum=0;                                                                                                               for(int i=from;i<end;++i)                                                                                                {                                                                                                                        sum+=i;                                                                                                              }                                                                                                                        return sum;                                                                                                              }                                                                                                                            int main()                                                                                                                   
{                                                                                                                            //写代码是为了完成某件事情,我们如何得知事情完成的怎么样呢?//进程退出码                                                                                                                                                 int num=AddtoTarget(1,100);if(num == 5050)       return 0;         else                                                                                                                       return 1;                                                                                                        return 0;             }  

$? 该符号永远记录最近一个进程在命令行中执行完毕时对应的退出码 

echo $? //查看进程退出码

这里下面的三个0是怎么回事呢?

这是因为echo 也是一个子进程,因此剩下的三个的是echo &?是一个echo子进程的退出码。

 (main函数的返回值实际上是 进程的退出码,用于表示进程是否是正确返回。)

  • 第一种:若退出码是0,则表示进程正确返回,0:success。
  • 第二种:若退出码为非0,则表示进程不正确返回,并且每个退出码都对应一个报错信息,退出码:报错信息。
  • 意义:将返回值返回给上一进程,用于监控进程的退出状态。出错时方便定位错误。

 有人就说了退出码都是数字,我们怎么知道它们分别对应什么错误?

还好c语言自带了一个查询退出码的函数——strerror

#include<stdio.h>
#include<string.h>int main()
{for(int i=0;i<200;++i){printf("%d: %s\n",i,strerror(i));                                                                                                                         } return 0;}

strerror记录了对应的退出码的映射信息,总共135个,这里截取了一小部分。

2.2.进程退出场景

  1. 此时代码运行完毕,结果正确 (这个时候main函数的返回值为0则为正确,0:success)
  2. 此时代码运行完毕,结果不正确(这个时候main函数的返回值非0则为不正确,返回值:报错信息)
  3. 此时代码异常终止(这个时候main函数的返回值不具有意义,此时应该去看退出信号)

 2.3.怎么退出进程

2.3.1.main函数return返回,其他函数return是调用结束。

return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返 回值当做 exit的参数。

2.3.2.任意地方调用exit。

我们来使用一下 

#include<stdio.h>  
#include<string.h>
#include<unistd.h>
#include<stdlib.h>int AddtoTarget(int from, int end){int sum = 0;for (int i = from; i <= end; ++i){sum += i;}exit(12);// return sum;  }int main(){int ret = AddtoTarget(1, 100);if (ret == 5050)return 0;elsereturn 1;}

 2.3.3.任意地方调用_exit(了解)

 我们来使用一下

#include<stdio.h>  
#include<string.h>
#include<unistd.h>
#include<stdlib.h>int AddtoTarget(int from, int end){int sum = 0;for (int i = from; i <= end; ++i){sum += i;}_exit(12);// return sum;  }int main(){int ret = AddtoTarget(1, 100);if (ret == 5050)return 0;elsereturn 1;}

对比exit和_exit发现,都可以使进程再任意地方结束。

2.3.4.exit()和_exit()的区别 

我们先来看两段代码

#include<stdio.h>  
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{printf("hello linux");sleep(2);exit(1);
}

 

#include<stdio.h>  
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{printf("hello linux");sleep(2);_exit(1);
}

对比发现,exit会刷新缓存区,而_exit并不会刷新缓存区——说明exit可能会调用_exit。

事实上: 

exit()和_exit()的底层区别:

  1. _exit():_exit()是系统调用接口的函数。
  2. exit():而exit()是把_exit()封装在内,并且增加了其他的函数,共同组合成exit()——是一个库函数。

exit是库函数,_exit是系统调用。库函数在系统调用上面。

如果缓存区在内存,exit调用_exit去终止进程,exit/_exit都应该会刷新缓冲区。
所以缓冲区在用户空间,是用户级的缓冲区 

 2.3.5.异常退出

·ctrl + c,信号终止

相关文章:

【Linux】进程控制1——进程创建和进程终止

1.进程创建 1.1.再谈fork 在linux中fork函数时非常重要的函数&#xff0c;它从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程。 #include <unistd.h> pid_t fork(void);//pid_t为整形 返回值&#xff1a;子进程中的fork()返回0&#xff…...

计算机图形学入门16:曲线

1.曲线 曲线&#xff08;Curves&#xff09;在图形学中应用非常广泛&#xff0c;比如&#xff1a;相机的拍摄路径、物体的移动路径、动画曲线、矢量字体等。如下图所示&#xff0c;是使用曲线到矢量字体的应用&#xff0c;通过移动一些控制点来改变字体。 2.贝塞尔曲线 2.1 贝…...

【Ruby基础01】windows和termux中搭建Ruby开发环境

windows下环境搭建 railsinstaller官方git地址 按照文档安装git、nodejs、yarn&#xff0c;安装教程百度一下。railsinstall可以从release页面下载最新版本4.1.0。 安装完成如下 安装RubyMine 下载RubyMine RubyMine下载地址 安装激活 下载文件&#xff0c;按照里面的流程…...

2406c++,iguana动态反射

原文 iguana是一个基于编译期反射的序化库,支持从结构序化到不同数据格式. iguana可序化一个C结构到json,xml,yaml和protobuf格式.这都是通过编译期反射实现的. 现在iguana也支持了动态反射,主要特征: 1,通过对象名创建对象实例 2,取对象所有字段名 3,根据字段名取字段值 4,根…...

干货分享——AB站帮你解决独立站收款难题

目前&#xff0c;国内已经有抖音、拼多多和淘宝平台推出“仅退款”售后服务&#xff0c;无疑是加剧了原本就在疯狂打价格战的国内电商的严峻现状&#xff0c;使得商家不得不担心被顾客“薅羊毛”。在国内电商环境严重“内卷”的情况下&#xff0c;拓宽海外市场不失为一大妙计。…...

C++继承与派生

1.基本知识 类的继承是新类从已有类那里获得特性&#xff0c;从已有的类产生新类的过程称为类的派生&#xff1b; 已有类称为基类或父类&#xff0c;派生出的新类则称为派生类或子类&#xff1b; 继承的功能&#xff1a; &#xff08;1&#xff09;使得基类与派生类之间建立…...

Survival Animations

一套生存游戏的动画集,包括采集、建造、捕鱼、剥皮/鞣制、篝火等更多内容。 总动画数:89 建造/制作 30 篝火 28 饮水 3 水壶 3 觅食 2 治疗 3 空闲 1 原始捕鱼 7 剥皮 1 矛捕鱼 4 伐木 5 下载:​​Unity资源商店链接资源下载链接 效果图:...

Cargo 教程

Cargo 教程 1. 引言 Cargo 是 Rust 编程语言的包管理器和构建工具。它为 Rust 项目提供了依赖管理、编译和打包等功能。本教程将详细介绍 Cargo 的基本用法,帮助您快速上手 Rust 项目开发。 2. 安装 Cargo 在开始使用 Cargo 之前,您需要确保已经安装了 Rust 编程语言。Ru…...

linux中“PXE高效批量装机”

在大规模的 Linux 应用环境中&#xff0c;如 Web 群集、分布式计算等&#xff0c;服务器往往并不配备光驱设备&#xff0c;在这种情况下&#xff0c;如何为数十乃至上百台服务器裸机快速安装系统呢&#xff1f;传统的 USB光驱、移动硬盘等安装方法显然已经难以满足需求。 PXE …...

emm, ComfyUI的作者从Stability.AI离职了

&#x1f356;背景 今天在更新ComfyUI的过程中&#xff0c;看到Manager中有这样一段描述&#xff1a; 嗯&#xff1f;做了新的官方网站&#xff1f;然后开始新篇章&#xff1f; 难道说ComfyUI的作者从Stability.AI离职了&#xff1f; 赶紧点开链接看了下&#xff0c;emm&…...

Redis-五种数据结构之列表(ziplist、quicklist)

列表 文章目录 列表压缩列表-ziplistziplist 定义级联更新 快速列表-quicklistquicklistNode 定义quicklist 定义quicklist常用操作其他操作quicklist 相对于普通链表优点quick应用场景在redis 中使用quicklist 列表数据类型可以存储一组按插入顺序排序的字符串&#xff0c;他很…...

记一次全设备通杀未授权RCE的挖掘经历

想来上一次挖洞还在一年前的大一下&#xff0c;然后就一直在忙活写论文&#xff0c;感觉挺枯燥的&#xff08;可能是自己不太适合弄学术吧QAQ&#xff09;&#xff0c;所以年初1~2月的时候&#xff0c;有空的时候就又会挖一挖国内外各大知名厂商的设备&#xff0c;拿了几份思科…...

【数据库编程-SQLite3(一)】sqlite3数据库在Windows下的配置及测试

学习分析 1、资源准备2、环境配置2.1、将资源包下载解压缩保存。2.2、在QT中创建工程,配置环境 3、测试配置3.1、 sqlite3_open函数3.2、sqlite3_close函数3.3、代码测试 1、资源准备 资源包 2、环境配置 2.1、将资源包下载解压缩保存。 解压缩得到以下文件 2.2、在QT中创建…...

YOLOv10改进 | 主干篇 | YOLOv10引入华为VanillaNet替换Backbone

1. VanillaNet介绍 1.1 摘要: 基础模型的核心是“越多越好”的理念,计算机视觉和自然语言处理领域取得的惊人成功就是例证。 然而,优化的挑战和变压器模型固有的复杂性要求范式向简单性转变。 在这项研究中,我们介绍了 VanillaNet,一种设计优雅的神经网络架构。 通过避免…...

C++ 迷宫问题

描述 定义一个二维数组 N*M &#xff0c;如 5 5 数组下所示&#xff1a; int maze[5][5] { 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, }; 它表示一个迷宫&#xff0c;其中的1表示墙壁&#xff0c;0表示可以走的路&#xff0c;只能横着走…...

【Linux】Linux文件系统中主要文件夹列举_作用说明

在Linux系统中&#xff0c;文件夹&#xff08;或称为目录&#xff09;的组织结构是系统功能和用户数据的重要组成部分。以下是Linux系统中一些主要文件夹的列举及其作用说明&#xff1a; / (根目录): 是Linux文件系统的起点。通常只包含其他目录&#xff0c;不建议直接在其中存…...

移植案例与原理 - HDF驱动框架-驱动配置(1)

HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码&#xff0c;内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦&#xff0c;便于开发者进行配置管理。应该&#xff0c;类似Linux DTS(Device Tree Source)设备树。 HC-GEN(HDF Configuration Generator)是…...

坚持刷题|反转链表

文章目录 题目思考实现1. 迭代方式实现链表翻转2. 递归方式实现链表翻转 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天继续链表&#xff1a;反转链表 题目 LCR 024. 反转链表 思考 翻转链表是一个常见的算法问题&a…...

升级和维护老旧LabVIEW程序

在升级老旧LabVIEW程序至64位环境时&#xff0c;需要解决兼容性、性能和稳定性等问题。本文从软件升级、硬件兼容性、程序优化、故障修复等多个角度详细分析。具体包括64位迁移注意事项、修复页面跳转崩溃、解决关闭程序后残留进程的问题&#xff0c;确保程序在新环境中的平稳运…...

sqlite数据库整体迁移进mysql整个流程并解决中文异常问题

咨询【QQ】 sqlite轻量数据还行&#xff0c;随着数据量增大&#xff0c;不得不迁移进mysql 首先 电脑执行 sqlite3 db.sqlite3 .dump > dump.sql 会把整个sqlite的数据导出进 dump.sql中 紧接着我们把sqlite的sql转换成mysql的sql语句&#xff0c;因为mysql语句和 sq…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...