【Linux】进程8——进程创建和进程终止

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,信号终止

 

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

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

相关文章

(BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)

6.开启 Spring Boot 特性有哪几种方式&#xff1f; 7.Spring Boot 需要独立的容器运行吗&#xff1f; 8.运行 Spring Boot 有哪几种方式&#xff1f; 9.Spring Boot 自动配置原理是什么&#xff1f; 10.Spring Boot 2.X 有什么新特性&#xff1f;与 1.X 有什么区别&#xff1f;…

Ubuntu server 24 (Linux) AdGuard Home +SmartDNS 安装配置 搭建去广告快速DNS

一 SmartDNS 安装 &#xff0c;可参考&#xff1a;Ubuntu server 24 (Linux) 安装部署smartdns 搭建智能DNS服务器-CSDN博客 二 安装AdGuard 1 下载地址&#xff1a;GitHub - AdguardTeam/AdGuardHome: Network-wide ads & trackers blocking DNS server 2 解压安装 #下…

基于FPGA的SM3加密算法优化(SM3加密算法三)

前文根据奇哥的方法使用FPGA实现了SM3加密算法&#xff0c;算法实现方式正确&#xff0c;但在并行度为2的情况下&#xff0c;在zynq7030ffg676-2也只能跑到50MHz&#xff0c;并行度为1也跑不到100MHz。 因此在了解原理的过程中&#xff0c;发现消息扩展和迭代过程其实可以全部放…

python的四个进度条

哈喽&#xff0c;我是快乐吗喽&#xff0c;今天简单的给大家介绍一下python的四个进度条工具&#xff0c;希望各位喜欢。 第一个进度条工具tqdm&#xff0c;好记点我叫她淘气大妈 安装tqdm库 pip install tqdm 基本用法 from tqdm import tqdm import timefor i in tqdm(ran…

彼长技以助己(5)量级思维

彼长技以助己&#xff08;5&#xff09;量级思维 数字感性与理性测试 我先讲一个可能发生在我们身边的故事&#xff1a;一个程序员在一个项目开发中使用了考虑到目前业务量少&#xff0c;快速写了一个冒泡排序&#xff0c;结果被经理批评了&#xff0c;然后他跑来找你诉苦&am…

AI漫画赛道,10分钟快速赚钱秘诀!

AI百宝箱-Chatgpt4.0、Midjourney绘画、人工智能绘画、AI换脸、AI图片放大、AI图片分析、AI图片融合https://h5.cxyhub.com/?invitationhmeEo7 先使用ChatGPT写小说 ComicAI 漫画小说生成网站 1. 创建小说漫画 2. 故事模板 3. 生成角色形…

递归查询和迭代查询

在域名解析过程中&#xff0c;一般有两种查询方式:递归查询和迭代查询。递归查询:服务器必需回答目标IP与域名的映射关系。迭代查询:服务器收到一次迭代查询回复一次结果&#xff0c;这个结果不一定是目标IP与域名的映射关系&#xff0c;也可以是其它DNS服务器的地址。 递归是某…

Java 反射的基本概念及其在框架中的应用

Java反射&#xff08;Reflection&#xff09;是Java语言中的一种特性&#xff0c;它允许程序在运行时检查和操作类、接口、字段和方法。反射提供了一种机制&#xff0c;使得Java程序可以动态地加载类、创建对象、调用方法、访问和修改字段。反射是Java动态性的重要体现&#xf…

项目经理与业务方沟通机制的6个重点

软件项目经理与业务方的有效沟通是项目成功的关键&#xff0c;通过定期对需求进行讨论和确认&#xff0c;有助于需求的精准理解&#xff0c;提高项目需求质量和决策效率&#xff0c;有利于团队间协作沟通&#xff0c;增强信任与合作&#xff0c;提高开发质量。如果双方间缺乏有…

旋转三角形加载动画

效果图: 完整代码: <!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>旋转三角形加载动画</title><style type="text/css">body {background: #ECF0F1;display: flex;justify-content: center;…

如何打造一份出色的文案策划求职简历?看完这篇你就明白了

从事文案策划多年&#xff0c;在简历打造上&#xff0c;也有些许心得&#xff0c;这些年面试通过率也在80%以上。 都说不会打造简历的文案人不是一个合格的文案&#xff0c;首先分享几点我的简历打造理念。 1、用写广告文案的思维写简历 如果把个人劳动力作为商品来看&#…

超详解——Python模块文档——基础篇

目录 1. Unix起始行 示例&#xff1a; 2. 对象和类型 示例&#xff1a; 3. 一切都是对象 示例&#xff1a; 4. 理解对象和引用 示例&#xff1a; 5. 理解对象和类型 示例&#xff1a; 6. 标准类型 示例&#xff1a; 7. 其他内建类型 示例&#xff1a; 8. 类型的类…

人工智能和机器学习这两个概念有什么区别?

什么是人工智能&#xff1f; 先来说下人工智能&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI&#xff0c;通俗来讲就是用机器去做在过去只有人能做的事。 人工智能最早是由图灵提出的&#xff0c;在1950年&#xff0c;计算机…

气膜建筑在体育和娱乐行业的多样化应用—轻空间

随着人们生活水平的提高和健康意识的增强&#xff0c;体育和娱乐行业的发展迎来了新的机遇和挑战。气膜建筑&#xff0c;作为一种新型建筑技术&#xff0c;因其独特的优势和广泛的应用场景&#xff0c;正在引领体育和娱乐行业的新潮流。 快速建设高品质体育场馆 气膜建筑以其快…

语音研究方向学术和工作资源清单

Speech-Resource 国内高校 清华大学北京大学上海交通大学中国科学院中国科学技术大学西北工业大学天津大学厦门大学昆山杜克大学浙江大学哈尔滨工业大学香港中文大学香港科技大学香港理工大学台湾大学 海外高校 剑桥大学牛津大学爱丁堡大学谢菲尔德大学蒙特利尔大学麻省理工大学…

《Brave New Words 》5.1 传递真相:偏见和虚假信息现状

Part V: Keeping Kids Safe 第五部分&#xff1a;确保孩子安全 Never travel faster than your guardian angel can fly. —Mother Teresa 永远不要比你的守护天使飞得更快。 ——特蕾莎修女 Distrust and caution are the parents of security. —Benjamin Franklin 不信任和谨…

数据结构基础(基于c++)

数据结构基础&#xff08;基于c&#xff09; 文章目录 数据结构基础&#xff08;基于c&#xff09;前言1. 递归、迭代、时间复杂度、空间复杂度2. 数据结构 数组与链表1. 数组2. 链表3. 动态数组4. 数组与链表对比 前言 参考资料&#xff1a;Hello 算法 (hello-algo.com) 1. 递…

假期已结束,大家都开始上班了吗

千行赏金APP&#xff1a;一站式悬赏任务平台详解 一、功能特点 千行赏金APP&#xff0c;作为一个综合性的悬赏任务平台&#xff0c;其功能特点突出&#xff0c;为用户提供了丰富的体验。首先&#xff0c;用户可以在平台上发布各类任务&#xff0c;如填写问卷、参与调研、试玩游…

MySQL高性能(MySQL锁)

MySQL性能系列 MySQL锁 前言1. 死锁机制2. 思维导图与锁划分介绍3. 粒度划分锁3.1. 全局锁3.2. 页级锁&#xff08;Page-level locking&#xff09;3.3. 表级锁&#xff08;Tables-level lock&#xff09;○ 共享锁&#xff08;表级&#xff09;○ 排他锁&#xff08;表级&…

【perl】环境搭建

1、Vscode Strawberry Perl 此过程与tcl环境搭建很类似&#xff0c;请参考我的这篇文章&#xff1a; 【vscode】 与 【tclsh】 联合搭建tcl开发环境_tclsh软件-CSDN博客 perl语言的解释器可以选择&#xff0c;strawberry perl。Strawberry Perl for Windows - Releases。 …