惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
Google Online Security Blog
Google Online Security Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Simon Willison's Weblog
Simon Willison's Weblog
T
Threat Research - Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
L
Lohrmann on Cybersecurity
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
Schneier on Security
Schneier on Security
S
Schneier on Security
T
Tor Project blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
WordPress大学
WordPress大学
The Hacker News
The Hacker News
Hacker News - Newest:
Hacker News - Newest: "LLM"
罗磊的独立博客
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Fortinet All Blogs
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
S
Security @ Cisco Blogs
PCI Perspectives
PCI Perspectives
Spread Privacy
Spread Privacy
W
WeLiveSecurity
SecWiki News
SecWiki News
A
About on SuperTechFans
H
Help Net Security
博客园 - 司徒正美
Recent Commits to openclaw:main
Recent Commits to openclaw:main
爱范儿
爱范儿
S
Securelist
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
月光博客
月光博客
Jina AI
Jina AI
博客园 - 叶小钗
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Recent Announcements
Recent Announcements
S
Secure Thoughts
The Cloudflare Blog
美团技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

Sehnsucht

记一次博客换图床的过程 观《花束般的恋爱》 读《活过》 东京 旅行篇 亲人逝去 我为什么想养鱼 防止AI爬取你的博客 「monthly 」博客重构 游戏全成就 好看的小说 人生的每一步都不会是浪费-2024年终 「weekly」星期五综合征 「weekly」听播客 杂谈 读《美丽新世界》 「weekly」社交媒体 恶性事件 新世界 「weekly」认知觉醒 美丽新世界 follow 「weekly」独立博客9问题 双十一买书 读《惊呆了!原来这就是社会学》 一次聊天与自我建设 2024-09月记 补番《relife》 树状数组简单理解 lvm简单使用 博客自动发布方案 某公众号废案 fail2ban基本使用 Podman 环境使用 Nginx Proxy Manager 最佳实践 2024-07同学聚会 vps使用podman部署freshrss Gitlab CICD 实践,思考与记录 装备升级:新的PC gitlab局域网搭建流程 FastMail迁移至GMail+Cloudflare Email Routing 读《黑客与画家》 leetcode 第 391 场周赛 Astro添加过渡后DarkModeToggle按钮失效 nuxt3使用echarts5渲染中国地图 人生刻度 又到凤凰花朵开放的时候 2023-05-10 实习结束 2023-04-26 广州博物馆游记 YOASOBI「たぶん」官方音乐视频 风灵玉秀-发如雪 带我的老哥离职了 从p10k转向Starship lunarvim国内安装踩坑记录 什么是对称加密非对称加密、密钥交换、数字签名、证书 强调体验的一种思考时间的方式 ArchLinux使用vscode编写latex报错The font "FontAwesome" cannot be found ArchLinux安装(移动硬盘)流程 yay一个或多个文件没有通过有效性检查! 2022年终 hugo建站伊始 clash设置relay前置代理(校园网破解改进记录) 群青 · YOASOBI · Ayase 华为 matepad pro 11使用体验 Nginx使用acme.sh免费安装ssl证书 永远属于你的安娜 在线 童年趣事 童心,是比野心更难得的梦想 2021年终总结 基于jeeSite的软件测试课程作业 流程记录 Linux不同用户安装不同版本jdk Wifi4更换Wifi6路由器的使用体验 Flask 上传图片并灰度显示 玩客云刷机debain个人记录 jython 简单入门 Jenkins 个人搭建流程记录 集成邮件系统(qq邮箱),gitlab服务器,freestyle风格 在Web项目中配置Log4j --指南-- Codeforces Round 753 (Div. 3) ABCDE JavaWeb servlet 使用Cookie记录用户访问次数 Codeforces Round Educational Codeforces Round 114 (Rated for Div. 2) ABC 2021牛客多校7 I xay loves or 2021牛客多校9 H Happy Number 2021牛客多校8 D OR 2021牛客多校5 B Boxes 2021牛客多校5 H Holding Two 2021牛客多校2 D Er Ba Game 2021牛客多校1 F Find 3-friendly Integers 2021牛客多校1 B Ball Dropping 记人生第一次投简历和笔试 原型模式 2021-2-20 雨时随记 关于一维差分数组的例子 halo个人建站 关于手机ping电脑和电脑ping手机 泛型类简单理解 CodeForces - 849C From Y to Y 2020牛客国庆集训派对day3 Leftbest 约瑟夫环问题---2020牛客国庆集训派对day2 AKU NEGARAKU mysql 5.7 忘记密码如何更改 CF 1099B Squares and Segments CF 998A Balloons CF 998B Cutting 链表应用之多项式相加 CF 1150A Stock Arbitraging CF 1199A City Day CF 1199B Water Lily CF 982A Row CF 934A A Compatible Pair CF 629B Far Relative’s Problem 651A Joysticks 651B Beautiful Paintings
浅谈fork函数
2021-10-22 · via Sehnsucht

谈谈进程

从程序员的角度进程有三种状态:

  • 进行 正在执行或者等待执行且最终被调度
  • 停止 进程被挂起且不会被调度,
  • 终止 三种可能:收到终止信号,从主程序返回,调用exit函数

关于进程的函数有exit,fork,wait等,本篇只描述fork

fork是一个很特殊的函数,用于克隆父进程,创建子进程

一个函数,却有两个返回,挺奇妙的

fork返回的是子进程的PID,即fork之后,子进程是返回的是0(子进程没有子进程了),而父进程返回子进程的PID

0:在子进程中,pid变量保存的fork( )返回值为0,表示当前进程是子进程 >0:在父进程中,pid变量保存的fork( )返回值为子进程的id值(进程唯一标识符) -1:创建失败

内核为fork( )完成以下操作:

  1. 为新进程分配一进程表项和进程标识符 进入fork( )后,内核检查系统是否有足够的资源来建立一个新进程。若资源不足,则fork( )系统调用失败;否则,内核为新进程分配一进程表项和唯一的进程标识符。

  2. 检查同时运行的进程数目 超过预先规定的最大数目时,fork( )系统调用失败。

  3. 拷贝进程表项中的数据 将父进程的当前目录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。

  4. 子进程继承父进程的所有文件 对父进程当前目录和所有已打开的文件表项中的引用计数加1。

  5. 为子进程创建进程上、下文 进程创建结束,设子进程状态为“内存中就绪”并返回子进程的标识符。

  6. 子进程执行 虽然父进程与子进程程序完全相同,但每个进程都有自己的程序计数器PC(注意子进程的PC开始位置),然后根据pid变量保存的fork( )返回值的不同,执行了不同的分支语句。

特点

1.调用一次返回两次

父进程返回一次子进程返回一次

2.并发执行

通过计算机调度

3.相同却又独立的地址空间

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
    int pid;
    int x = 1;
    pid = fork();
    if (pid == 0) {
        printf("chind : x=%d address=%d\n", ++x, &x);
        exit(0);
    }
    printf("parent : x=%d address=%d\n", --x, &x);
    exit(0);
}

这样的一个函数 我们输出的是

[root@Cai test]# ./test1
parent : x=0 address=-1911367976
[root@Cai test]# chind : x=2 address=-1911367976

由此可见,内存地址完全一样,但是由于是不同的进程,虽然有相同的栈,相同的堆,相同的变量值和地址,但是由于是独立的,对x的改变也是独立的

4.共享文件

例如stdout文件,子进程继承了父进程的打开文件,并指向屏幕,所以父进程和子进程的输出都是指向屏幕

练习1

题目来源:csapp练习8.2

问:父进程和子进程输出什么

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
    int x = 1;
    if (fork() == 0) 
        printf("p1: x=%d\n", ++x);
    printf("p2: x=%d\n", --x);
    exit(0);
}

原来的想法:

如果fork等于0,那么并没退出,还需要执行p2的输出,所以:先进行父进程的输出,只输出p2,再进行子进程的输出,p1和p2

p2: x=0
p1: x=2
p2: x=1

事实上:

进程终止的时候,内核并非立即把它删除,而是保持在一种已终止的状态,直到被他的父进程回收.终止了但还没回收的进程叫僵尸进程

由于父进程终止,子进程还在运行,那么内核会将安排init进程成为它孤儿进程的父进程,init进程是所有进程的祖先(进程),僵尸进程没有运行,但是仍然消耗内存资源

[root@Cai terminateParent]# ./test
p2: x=0
[root@Cai terminateParent]# p1: x=2
p2: x=1

佐证代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
    int x = 1;
    if (fork() == 0) {
        printf("parent pid=%d\n", getppid());
        printf("p1: x=%d\n", ++x);
    }
    printf("p2: x=%d\n", --x);
    exit(0);
}

结果:

[root@Cai terminateParent2]# ./test
p2: x=0
[root@Cai terminateParent2]# parent pid=1
p1: x=2
p2: x=1

参考

C语言编译过程 深入理解计算机系统csapp第三版第8章8.4(P513)