首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux系统 —— 进程控制系列 - 进程的创建与终止 :fork与exit

Linux系统 —— 进程控制系列 - 进程的创建与终止 :fork与exit

作者头像
迷迭所归处
发布于 2024-12-24 01:34:13
发布于 2024-12-24 01:34:13
19700
代码可运行
举报
文章被收录于专栏:动态规划动态规划
运行总次数:0
代码可运行

1. 进程创建

1.1 再探fork函数初识

我们之前应该聊过fork函数了,具体可以看看这篇:

Linux系统 —— 进程系列 - 进程的概念,PCB与PID和fork_linux top adbd是什么线程-CSDN博客

https://blog.csdn.net/hedhjd/article/details/144299919?spm=1001.2014.3001.5501今天我们来具体聊一聊fork函数

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

fork会有两个返回值:给子进程返回0,给父进程返回子进程pid

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
pid_t fork(void);
返回值:子进程中返回0,⽗进程返回⼦进程pid,出错返回 - 1

当进程调用fork函数,当控制转移到内核中的fork代码后,内核应该: 1. 分配新的内存块和内核数据结构给子进程 2. 将父进程部分数据结构内容拷贝到子进程 3. 添加子进程到系统进程列表当中 4. fork返回,开始调度器调度 在默认情况下,父进程和子进程代码和数据都是共享的,但是如果子进程进行写入数据或者代码,那么子进程就会对代码或者数据发生对应的写实拷贝,所以以写实拷贝的方式来实现我们父子进程的独立性,这样的话互不干扰

当⼀个进程调用fork之后,就有两个⼆进制代码相同的进程。而且它们都运行到相同的地方,看如下程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int main(void)
{
	pid_t pid;

	printf("Before: pid is %d\n", getpid());

	if ((pid = fork()) == -1)perror("fork()"), exit(1);

	printf("After:pid is %d, fork return %d\n", getpid(), pid);
	sleep(1);

	return 0;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
运⾏结果:
[kiana@localhost ~]# . / a.out
Before : pid is 43676
After : pid is 43676, fork return 43677
After : pid is 43677, fork return 0

这⾥看到了三⾏输出,⼀⾏before,两⾏after。进程43676先打印before消息,然后它有打印after。另⼀个after消息有43677打印的。注意到进程43677没有打印before,为什么呢?如下图所示:

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

1.2 写时拷贝 一般来说,父子代码共享,父子再不写入时,数据也是共享的,当任意⼀⽅试图写⼊,便以写时拷贝的方式各⾃⼀份副本

写实拷贝其实就是子进程赋值父进程的PCB以及进程地址空间以及页表。 然后页表的映射物理内存是相同一份数据。 但是当子进程想要修改的时候, 由于进程的独立性, 子进程修改不能影响父进程的数据,那么就要发生写时拷贝(重新映射)

意思就是说, 一开始,子进程拷贝父进程的PCB。 虚拟地址空间, 页表。 所以父子进程中地址空间中的数据段和代码段映射到物理内存也是一样的。 但是这个时候页表会让他们都为只读状态, 如果后续的过程中子进程或者父进程都是只读, 那么就没有问题。 但是只要其中一个发生修改, 那么这个进程对应的页表就会重新映射空间 写实拷贝的原理就是:延时申请、按需申请

因为有写时拷⻉技术的存在,所以⽗⼦进程得以彻底分离离,完成了进程独立性的技术保证! 写时拷贝,是⼀种延时申请技术,可以提⾼整机内存的使⽤率


2. 进程的退出 1. 代码运行完毕,结果正确 2. 代码运行完毕,结果不正确 3. 代码异常终⽌

退出分为正常退出和不正常退出,我们上面的1和2就是正常退出,3就是不正常退出 而运行结果也就是return某个数字或者exit某个数字, 这里的某个数字就是运行结果,也被成为退出码 我们可以使用echo $?来打印我们最近一个进程退出时的退出码

这个时候我们就有一个问题:为什么运行码的表征结果最终会返回给bash进程?答案是:对于进程来说, 我们的进程的父进程会关心我们进程,所以会将结果返回给bash进程 父进程关心子进程什么呢?答案是:父进程关心子进程退出时代码跑完之后为什么结果是不正确的 代码只有0是成功的, 只要是非0那么就是不正确,而不正确的非零数字, 就会代表不同的推出原因:退出码

都是如果是运行异常的话,那么 程序的退出码基本可以不看,因为异常就代表没有正常执行到退出程序, 这个时候退出码没有太大意义 如果一个程序发生了异常终止,本质上就是进程收到了对应的信号 如果我们没有发信号的时候, 这个程序正在正常的跑,不出意外的话这个进程是能够无限循环的, 但是一旦我们给进程发一个信号, 那么这个进程就会被检测为异常, 进而被操作系统杀掉,由此可以看出:进程的本质就是接收到了对应的信号


3. exit

exit就是用来终止进程的,进程终⽌的本质是释放系统资源,就是释放进程申请的相关内核数据结构和对应的数据和代码 先看一段代码:

运行结果:

我们发现,运行结果只执行到第一个printf,并没有执行第二个,因为这个代码进程跑不到第二个printf就会遇到exit直接终止 一个问题:我们上面的程序的退出码是什么?答案是40, 因为对于exit来说, 无论exit在什么位置, 只要exit出现, 就会终止掉调用该函数的进程

3.1 exit和_exit区别 简单来说就是exit是C语言里的,而_exit是系统的 具体区分就是: 进程如果调用的是我们exit的接口的话,那么exit()退出时会进行资源的回收,会进行缓冲区的刷新 进程如果调用的是我们_exit的接口的话,那么_exit()退出时会进行资源的回收,不会进行缓冲区的刷新

_exit函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
void _exit(int status);
//参数:status 定义了进程的终⽌状态,⽗进程通过wait来获取该值

虽然status是int,但是仅有低8位可以被⽗进程所用,所以_exit(-1)时,在终端执⾏$?发现 返回值是255

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//_exit
int main()
{
	printf("hello");

	_exit(0);
}

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux] # . / a.out
[root@localhost linux]#

exit函数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <unistd.h>
void exit(int status);

exit最后也会调⽤_exit, 但在调⽤_exit之前,还做了其他⼯作:

1. 执行用户通过 atexit或on_exit定义的清理函数

2. 关闭所有打开的流,所有的缓存数据均被写⼊

3. 调⽤_exit

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//exit
int main()
{
	printf("hello");

	exit(0);
}

运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[root@localhost linux] # . / a.out
[root@localhost linux]#hello

return退出 return是⼀种更常⻅的退出进程⽅法。执⾏return n等同于执⾏exit(n),因为调⽤main的运⾏时函数会将main的返回值当做 exit的参数

未完待续~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用Python生成一张用于登陆验证的字符图片
Python Pillow库的简单使用 使用Python生成一张用于登陆验证的字符图片, 代码使用了Pillow,Anaconda已经默认安装此库,如果你使用的是官方版的Python需要先下载此库。 代码如下,在注释中予以说明: from PIL import Image, ImageDraw, ImageFont, ImageFilter import random #定义一个生成随机字符的函数 ASII码表 48-57: 0-9 65-90: A-Z 97-122: a-z def randCha
Steve Wang
2018/02/05
8740
使用Python生成一张用于登陆验证的字符图片
Python实战-游戏(四则运算小游戏)
编程世界既神秘又充满乐趣,而今天,我们又将一起踏上学习编程的奇妙旅程,今天我们将用python通过编写简单而有趣的四则运算游戏,探索代码背后的魔法力量。无论你是完全的初学者还是有一定经验的编程爱好者,这个项目都将为你打开编程的大门,让你体验到编程的乐趣与成就感。
一个风轻云淡
2024/03/22
3110
Python简易验证码生成程序
from PIL import Image, ImageDraw, ImageFont import random import string #所有可能的字符,主要是英文字母和数字 characters = string.ascii_letters+string.digits #获取指定长度的字符串 def selectedCharacters(length): '''length:the number of characters to show''' result = "" fo
Python小屋屋主
2018/04/16
7410
python通过pil生成图片验证码
# -- coding: utf-8 -- 导入三个模块 import Image,ImageDraw,ImageFont import random import math '''基本功能''' 图片宽度 width = 100 图片高度 height = 40 背景颜色 bgcolor = (255,255,255) 生成背景图片 image = Image.new('RGB',(width,height),bgcolor) 加载字体 font = ImageFont.truetype('FreeSan
代码伴一生
2021/11/03
6260
利用机器学习识别验证码(从0到1)
利用机器学习识别验证码的思路是:让计算机经过大量数据和相应标签的训练,计算机习得了各种不同标签之间的差别与关系。形成一个庞大的分类器。此时再向这个分类器输入一张图片。分类器将输出这个图片的“标签”。图片识别过程就完毕了。
李玺
2021/11/22
8470
利用机器学习识别验证码(从0到1)
pyocr库
使用预先训练好的模型(例如Tesseract中的LSTM模型),对提取的特征进行模式匹配,以确定每个字符的可能身份。
哲学家阿多诺
2024/09/01
2200
pyocr库
Django之随机图形验证码
一个input输入框和一个用div包裹的img标签,用Bootstrap的栅格系统各占6格(只是为了美观,可以不用样式)
py3study
2020/01/17
1.1K0
四则运算作业
代码: # -*- coding: utf-8 -*- import random from fractions import Fraction from envs.py3k.Lib.symbol import except_clause print ("小学四则运算测试:(结果保留1位有效数字)") ops = ['+', '-', '*', '/'] # 锟斤拷锟斤拷锟� ans = "" # 锟矫伙拷锟截达拷 num = 1 # 锟斤拷锟� rightnum = 0 t = 0 while
py3study
2020/01/17
5030
python实现生成验证码的逻辑
 假设我们有一个fonts的文件夹,里面有1.ttf,2.ttf,3.ttf三个字体文件 具体代码实现代码codes.py: # coding:utf8 from PIL import ImageDraw, ImageColor, ImageFile, ImageFont, ImageFilter, Image import random import os import uuid class Codes: # 定义随机字符 def random_chr(self):         num = 
禹都一只猫olei
2018/05/25
5510
利用Python几行代码批量生成验证码
附件:代码地址 https://github.com/Testworm/app_ui/blob/master/authCode.py 
互联网金融打杂
2019/12/11
6920
利用Python几行代码批量生成验证码
Python3实现验证码
Python3 实现创建验证码图片 一:准备工作,需要安装PIL,安装方式,pip install Pillow 二:具体实现 #!/usr/bin/env python3 # coding:UTF-8 """" 文件说明: """ from PIL import Image, ImageDraw, ImageFont import random import string import os def get_code(width=100, height=40, fontSize=35):
py3study
2020/01/10
3710
python3 pillow生成简单验
使用Python的pillow模块 random 模块随机生成验证码图片,并应用到Django项目中
py3study
2020/01/02
4340
[置顶] 用python生成验证码图片
基本上大家使用每一种网络服务都会遇到验证码,一般是网站为了防止恶意注册、发帖而设置的验证手段。其生成原理是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR)。下面就详细讲解如何生成验证码。
代码伴一生
2021/11/02
1.7K0
为什么每次登录系统都有烦人的验证码?
每次登录系统的时候总是要输入烦人的验证码,那么我们今天就思考这个问题,为什么要有验证码这个功能?很多伙伴应该都知道:
不安分的猿人
2020/06/15
1.2K0
使用Python生成基础验证码教程
pillow是Python平台事实上的图像处理标准库。PIL功能非常强大,但API却非常简单易用。 所以我们使用它在环境里做图像的处理。
步履不停凡
2019/09/11
6520
纯代码系列:Python实现验证码图片(PIL库经典用法用法,爬虫12306思路)
现在的网页中,为了防止机器人提交表单,图片验证码是很常见的应对手段之一。这里就不详细介绍了,相信大家都遇到过。
用户2966292
2020/10/23
8240
Django实战-信息资讯-图形验证码
Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。
小团子
2019/07/18
6210
Django实战-信息资讯-图形验证码
Day21第三方模块Pillow&requests
Pillow PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了。PIL功能非常强大,但API却非常简单易用。 由于PIL仅支持到Python 2.7,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。 模糊效果: from PIL import Image, ImageFilter # 打开一个jpg图像文件,注意是当前路径: im
林清猫耳
2018/04/26
8140
随机验证码
Python生成随机验证码,需要使用PIL模块.python3则是pillow 安装: ? 1 pip3 install pillow 基本使用 1. 创建图片 ? 1 2 3 4 5 6 7 8
用户1214487
2018/01/24
1.8K0
Pillow模块图片生成
0825自我总结 Pillow模块图片生成 一.模块安装 pip3 install pillow 二.模块的载入 import PIL 三.django结合img标签生成图片 img.html <img src='/img/'> url.py from django.conf.urls import url from django.contrib import admin #主路由导入视图内函数 from app import views urlpatterns = [ url(r'^img/',
小小咸鱼YwY
2019/09/11
1.3K0
相关推荐
使用Python生成一张用于登陆验证的字符图片
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验