Linux 第十一章

news2024/10/7 14:23:31

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

fork

事例

一个函数,竟然有两个返回值???

调用 fork() 后会产生以下结果:

fork的一般写法

 fork的应用

fork的原理

fork干了什么事

为什么fork会有两个返回值

为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?

fork之后,父子进程谁先运行?

如何理解同一个变量,会有不同的值?


fork

fork() 系统调用是Unix和类Unix操作系统(包括Linux)中的一个重要系统调用之一。它用于创建一个新的进程,称为子进程,该子进程是调用进程的副本。

fork() 的一般形式如下:

#include <unistd.h> pid_t fork(void);
其中 pid_t 是一个整数类型,通常是int,表示进程ID。

调用 fork() 后,操作系统会复制父进程的所有内容(包括代码、数据等),然后在子进程中开始执行。这样就创建了两个完全独立的进程,它们可以同时运行不同的代码。

事例

[BCH@hcss-ecs-6176 9_23]$ cat code.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
        printf("我是一个父进程,我的pid%d,ppid:%d\n",getpid(),getppid());
        //创建子进程!,bash他也是用c语言写的,命令行启动的进程,都是bash的子进程,大概估摸着,bash源代码中创建子进程用的就是这个fork()
        fork();
        printf("我是一个进程,我的pid%d,ppid:%d\n",getpid(),getppid());//这个函数只调用了一次
        sleep(1);
}

程序运行:
[BCH@hcss-ecs-6176 9_23]$ ./mycode
我是一个父进程,我的pid24782,ppid:21864
我是一个进程,我的pid24782,ppid:21864
我是一个进程,我的pid24783,ppid:24782

总结:只有父进程会执行fork之前的代码(一定),fork之后,父子进程都要执行后续的代码

一个函数,竟然有两个返回值???

在 Linux 中,fork() 是一个系统调用,用于创建一个新的进程。当调用 fork() 时,操作系统会复制当前进程的副本,并将其作为新进程运行。这个新的进程称为子进程,而调用 fork() 的原始进程称为父进程。

调用 fork() 后会产生以下结果:

* 如果调用成功,则在父进程中返回子进程的 ID,而在子进程中返回 0。

* 如果调用失败,则在父进程中返回 -1,表示出现了错误。

父进程和子进程将在 fork() 调用之后的代码行处继续执行,但是它们拥有各自独立的进程空间和资源。子进程是父进程的一个副本,包括内存、文件描述符等。子进程可以执行不同的指令,或者通过调用 exec() 系列函数来执行其他程序。

fork的一般写法

1.我们为什么要创建子进程

我们想让子进程协作父进程完成一些工作,这些工作是单进程解决不了的

例如:我们的音乐,想要边下载,边播放

2.我们创建子进程是为了让子进程和我父进程做一样的事情吗?

肯定不是!

我们创建子进程,就是为了让子进程和父进程做不一样的事情,执行不一样的代码

我可以通过fork的返回值,判断谁是父,谁是子,然后让他们执行不同的代码片段!!

 fork的应用

[BCH@hcss-ecs-6176 9_23]$ cat code.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
        
        printf("我是一个父进程,我的pid%d,ppid:%d\n",getpid(),getppid());
        pid_t id=fork();
        //fork之后,用if进行分流
        if(id<0)return 1;
        else if(id==0)
        {
                //child
                while(1)
                {
                        printf("我是子进程:pid:%d,ppid:%d,ret:%d,我正在执行下载任务\n",getpid(),getppid(),id);
                        sleep(1);
                }
        }
        else
        {
                //parent
                while(1)
                {               
                        printf("我是父进程:pid:%d,ppid:%d,ret:%d,我正在执行播放任务\n",getpid(),getppid(),id);
                        sleep(1);
                }
        }
        return 0;
}

[BCH@hcss-ecs-6176 9_23]$ ./mycode
我是一个父进程,我的pid10090,ppid:21864
我是父进程:pid:10090,ppid:21864,ret:10091,我正在执行播放任务
我是子进程:pid:10091,ppid:10090,ret:0,我正在执行下载任务
我是父进程:pid:10090,ppid:21864,ret:10091,我正在执行播放任务
我是子进程:pid:10091,ppid:10090,ret:0,我正在执行下载任务
我是父进程:pid:10090,ppid:21864,ret:10091,我正在执行播放任务
我是子进程:pid:10091,ppid:10090,ret:0,我正在执行下载任务
^C

总结:奇怪的现象
1)if和else里的代码同时执行
2)两个死循环同时运行

fork的原理

fork干了什么事

为什么fork会有两个返回值

如果一个函数已经到return了,它的核心工作做完了吗?

做完了。

fork就是一个函数

fork之后代码共享!!!

return也是代码,return也要被共享!!

父进程要被调度,就要执行return

子进程要被调度,就要执行return

为什么fork的两个返回值,会给父进程返回子进程pid,给子进程返回0?

因为子进程的pid是唯一标识子进程的,父进程可以通过子进程的pid对子进程进行管理

1) 对于父进程:fork() 返回子进程的进程 ID(PID),即一个正整数值。父进程可以根据这个返回值来管理和控制子进程,例如等待子进程结束、发送信号给子进程等。父进程可以使用这个 PID 来识别和跟踪它创建的子进程。

2)对于子进程:由于 fork() 是在子进程中调用的,所以子进程并不需要父进程的 ID。为了简化子进程的处理逻辑,fork() 特意将其返回值设为 0。这样,在子进程中通过检查返回值是否为 0 可以确定自己是子进程,并在之后的代码中执行特定的子进程逻辑。

fork之后,父子进程谁先运行?

1)创建完成子进程,只是一个开始,创建完成子进程之后,系统的其他进程,父进程和子进程,接下来要被调度执行的!

2)当父进程的pcb都被创建并在 运行队列 中排队的时候,哪一个进程的pcb先被选择调度,那个进程就先运行!!

3)由各自pcb中的调度信息(时间片、优先级等)+调度器的算法共同决定的,总而言之,由操作系统自主决定!!!

所以父子进程谁先运行是不确定的

如何理解同一个变量,会有不同的值?

如果启动一个qq、微信、浏览器,这些都是进程,杀掉微信进程,qq进程还在吗?浏览器进程还在吗?还在!!

如果我们,父子进程,父进程被杀掉,子进程还在吗?或者返回过来?

还在!!

总结:进程之间运行的时候,是具有独立性的!无论是什么关系!

这个独立性是怎么做到的呢?

进程的独立性,首先表现在有各自的pcb,进程之间不会影响!代码本身是只读的,是不会影响代码!数据父子会修改的!代码共享,数据各自进程必须想办法各自私有一份!!

如何私有一份数据呢?

写时拷贝

创建子进程的时候,以浅拷贝的方式进行共享代码

父子任何一个尝试对他做写入时,把要修改的变量以深拷贝的形式给拷贝一份。

fork返回的值id,返回的本质是不是写入?是写入

id是不是父进程定义的变量?肯定是,保存就是数据

返回的时候,发生了写时拷贝

怎么同一个变量,同一个地址,会有不同内容?

这个地址,绝对不是物理地址!

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 

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

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

相关文章

比较美观即将跳转html源码

源码介绍 比较美观即将跳转html源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 源码截图 比较美观的一个跳转界面&#xff0c;修改方法如上&…

【Spring】IOC/DI中常用的注解@Lazy、@Scope与@Conditional

目录 1、Lazy 懒加载bean 1.1、与component配合使用 1.2、与Bean注解配合使用 2、Scope bean的作用域 2.1、不指定Scope 2.2、指定Scope为 prototype 3、Conditional 条件注解 1、Lazy 懒加载bean Lazy用于指定单例bean实例化的时机&#xff0c;在没有指定此注解时&…

异常处理Exception(一)

文章目录 1、添加异常捕捉2、链式CATCH3、一个CTACH捕捉多个异常4、捕捉所有异常总结 有些代码可以通过语法检查&#xff0c;但运行时会发生错误而崩溃&#xff0c;比如除数是0的情况。对于这类代码&#xff0c;需要使用 TRY&#xff0c; CATCH进行异常捕捉&#xff0c;避免代…

ubuntu24.04 正式放弃VNC

1、ubuntu22.04支持情况 去年9月在22.04中测试发现由于gnome启用Wayland桌面&#xff0c;然而Wayland和vnc兼容不佳&#xff0c;就已经黑屏等问题&#xff0c;当时是vnc和ms-rd(微软远程桌面)两个菜单。 Ubuntu22.04 vnc远程黑屏_ubuntu 远程桌面vnc黑屏-CSDN博客文章浏览阅读…

FreeRTOS之列表

1.FreeRTOS的列表和列表项十分重要。列表类相当于链表&#xff0c;列表项则相当于链表中的节点。列表项的地址是非连续的&#xff0c;列表项的数量可随时修改。在OS中的任务状态和数量会发生改变&#xff0c;因此使用列表可以很好的满足需求。 列表和列表项的相关定义与操作函…

基于51单片机的8路抢答器—计分功能

基于51单片机的8路抢答器 &#xff08;仿真&#xff0b;程序&#xff09; 功能介绍 具体功能&#xff1a; 1.主持人按下复位后数码管依次显示选手的编号和分数&#xff1b; 2.显示结束后主持人才可以按开始按键&#xff1b; 3.数码管倒计时10秒&#xff0c;选手开始抢答&a…

Jenkins邮件发送失败问题解决

如下提示为 Extended E-mail Notification开启Debug模式下显示的错误信息&#xff0c; (Debug模式设置方法&#xff1a;Dashboard-> manage Jenkins->configure System)DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 DEB…

Qt窗口

QMainWindow Qt 窗⼝ 是通过 QMainWindow类 来实现的。 QMainWindow 是⼀个为⽤⼾提供主窗⼝程序的类&#xff0c;继承⾃ QWidget 类&#xff0c;并且提供了⼀个预定义的 布局。QMainWindow 包含 ⼀个菜单栏&#xff08;menu bar&#xff09;、多个⼯具栏(tool bars)、多个浮动…

HarmonyOS NEXT应用开发之适配挖孔屏案例

介绍 本示例介绍使用屏幕属性getDefaultDisplaySync、getCutoutInfo接口实现适配挖孔屏。该场景多用于沉浸式场景下。 效果图预览 使用说明 加载完成后顶部状态栏时间和电量显示位置规避了不可用区域。 实现思路 通过setWindowLayoutFullScreen、setWindowSystemBarEnable…

自制贪吃蛇小游戏

此片文章涉及到到控制台设置的相关操作&#xff0c;虚拟键码&#xff0c;宽字符输出等&#xff0c;有些地方大家可能会看不懂&#xff0c;可以阅读以下文章来进一步了解&#xff1a; 控制台程序设置-CSDN博客 效果展示&#xff1a; QQ2024428-181932 源码已放在文章结尾 目录 …

Python | Leetcode Python题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution:def canJump(self, nums: List[int]) -> bool:n, rightmost len(nums), 0for i in range(n):if i < rightmost:rightmost max(rightmost, i nums[i])if rightmost > n - 1:return Truereturn False

AHB传输---等待传输

等待传输 slave在需要更多时间支持或采样数据时使用HREADYOUT信号插入等待状态。在等待传输期间&#xff0c;master对传输类型和地址的更改受到限制。 1. 在等待状态下传输类型的变化 当slave请求等待状态时&#xff0c;master不得更改传输类型&#xff0c;除非是以下状态&a…

Spring AOP是什么?可以拿它做什么?

Spring AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&#xff09;是Spring框架提供的一种重要特性&#xff0c;它通过在应用程序的横切关注点&#xff08;Cross-cutting Concerns&#xff09;中&#xff0c;将重复性的代码和逻辑分离出来&#xff0c;以…

青年夜校 | 李良济中医课堂,赋能“夜生活”,传承中医药文化

下班后的苏州年轻人都在干什么&#xff1f; 约饭看电影&#xff1f; 宅家打游戏&#xff1f; 最近&#xff0c;一种全新的“夜生活”模式开启啦&#xff01; 那就是—— 去家门口的夜校&#xff0c;学习中医和中药&#xff01; 1 家门口的夜校 解锁正确的中医养生法 4月…

Matlab实现CNN-LSTM模型,对一维时序信号进行分类

1、利用Matlab2021b训练CNN-LSTM模型&#xff0c;对采集的一维时序信号进行分类二分类或多分类 2、CNN-LSTM时序信号多分类执行结果截图 训练进度&#xff1a; 网络分析&#xff1a; 指标变化趋势&#xff1a; 代码下载方式&#xff08;代码含数据集与模型构建&#xff0c;附…

LabVIEW自动剪板机控制系统

LabVIEW自动剪板机控制系统 随着工业自动化的快速发展&#xff0c;钣金加工行业面临着生产效率和加工精度的双重挑战。传统的手动或脚踏式剪板机已无法满足现代生产的高效率和高精度要求&#xff0c;因此&#xff0c;自动剪板机控制系统的研究与开发成为了行业发展的必然趋势。…

消失了一个月,失踪人口回归!

大家好&#xff0c;我是前端队长。前端程序员&#xff0c;2023年开始玩副业。玩过AI绘画&#xff0c;公众号爆文项目&#xff0c;目前在做AI代写&#xff0c;累计变现五位数。 最近比较忙&#xff0c;而且没有意识到持续分享的重要性。 周六的时候&#xff0c;参加了武汉老徐合…

prompt提示词:AI英语词典,让AI教你学英语,通过AI实现一个网易有道英语词典

目录 英语词典提问技巧效果图&#xff1a;提示词&#xff1a; 英语词典提问技巧 随着AI工具的出现&#xff0c;学英语也可以变得很简单&#xff0c;大家可以直接通过AI 来帮助自己&#xff0c;提高记忆单词的效率&#xff0c;都可以不需要网易有道词典了&#xff0c;今天我教大…

Docker容器:数据管理与镜像的创建(主要基于Dockerfile)

目录 一、Docker 数据管理 1、数据卷&#xff08;Data Volumes&#xff09; 2、数据卷容器&#xff08;DataVolumes Containers&#xff09; 二、容器互联&#xff08;使用centos镜像&#xff09; 三、Docker 镜像的创建 1、基于现有镜像创建 2、基于本地模板创建 3、基…