操作系统(第四周 第二堂)

目录

回顾

进程运行

进程的创建

 进程的工作

举例

进程的删除

举例1(走到return 0结束)

举例2(利用exit(1)结束)

进程通信 

共享内存

生产者算法

消费者算法

消息传递 

定义

 算法实现

总结


回顾

上文的重点就两个内容:一、进程调度的理解;二、队列图以及调度程序

其中进程调度的理解有:一、进程本身角度调度理解;二、计算机整体角度理解进程管理和调度

队列图共有五个队列:I/O队列、中断队列、就绪队列、时间片过期队列、创建子进程队列

调度程序:长期调度程序、短期调度程序

进程运行

研究完进程调度,现在我们来研究进程的运行,研究进程运行前要先看进程是如何创建、删除的

一个进程的一生包括:创建、工作、被调度、删除

进程的创建

所有进程(除了Pid=0的初始进程)都是由父进程创建产生

定义:创建进程称为父进程,被创建进程称为子进程

每一个进程都采用进程标识符来唯一确定进程,子进程和父进程得pid不同

进程创建必备的两个指令:fork()、exec()

fork():

一、创建子进程,子进程和父进程完全相同(虚拟地址也相同,但是物理空间实际地址不同)。完全相同也意味着父进程fork后的程序计数器为fork函数结束位置,而子进程的程序计数器也为fork函数结束位置

二、在父进程中返回子进程的pid,在子进程中返回0

三、创建子进程也意味着要在内核中新建PCB(进程控制块)

exec():

一、以新程序来取代原进程的内存空间,包括程序、栈等进程所有的成分

二、exec后子进程就有了新的虚拟地址空间,可以认为“脱离”父进程的限制

三、exec后子进程的PID保持不变

 进程的工作

进程是并行工作的,即子进程被父进程创建后和父进程一起工作(父进程利用wait(NULL)除外,该方法让父进程在子进程结束后才工作)

举例

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>// 测试创建子进程函数 pid_t fork();
int main()
{pid_t pid = fork();if(-1 == pid){//创建子进程失败return -1;}if(0 == pid){//子进程printf("I am child, my fork:%d\n", pid);printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am child, I have finished\n");  }else{//父进程 printf("I am father, my fork:%d\n", pid);      printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am father, I have finished\n");   }return 0;
}

执行结果为:

程序运行的关键点: 

1、父进程先运行:由于子进程由fork函数创建,所以需要耗费一些时间。

2、父子进程并行运行:父进程利用sleep函数休息时,可以看到子进程也输出了其值,说明父子进程目前共同在运行

3、fork返回值:父进程的fork返回值为子进程的pid,子进程的fork返回值为0

4、pid是进程标识符:子进程和父进程的pid的值不同

进程的删除

进程的删除主要有两种:

1、进程走到return 0 自己结束 

2、进程调用exit(1)结束

举例1(走到return 0结束)

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>// 测试创建子进程函数 pid_t fork();
int main()
{pid_t pid = fork();if(-1 == pid){//创建子进程失败return -1;}if(0 == pid){//子进程printf("I am child, my fork:%d\n", pid);printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am child, I have finished\n");  }else{//父进程 wait(NULL) printf("I am father, my fork:%d\n", pid);      printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am father, I have finished\n");   }printf("%d 号进程已结束\n",pid);return 0;
}

 结果为:

关键点:在父进程中调用wait(NULL)函数让父进程在子进程结束后才开始运行 

举例2(利用exit(1)结束)

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>// 测试创建子进程函数 pid_t fork();
int main()
{pid_t pid = fork();if(-1 == pid){//创建子进程失败return -1;}if(0 == pid){//子进程printf("I am child, my fork:%d\n", pid);printf("I am child, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am child, I have finished\n");exit(1);  }else{//父进程 wait(NULL) printf("I am father, my fork:%d\n", pid);      printf("I am father, my pid:%d, ppid:%d\n",getpid(),getppid());sleep(5);printf("I am father, I have finished\n");   }printf("%d 号进程已结束\n",pid);return 0;
}

执行结果为:

关键点:子进程运行到exit函数后就自己删除自己,父进程开始运行 

进程通信 

操作系统内并发执行的进程可以是独立的也可以是协作的,协作完成的进程就涉及到进程间通信

进程通信主要有两种方式:1、共享内存  2、消息传递

图中关键点: 

1、共享内存没有内核参与,消息传递需要内核参与

2、共享内存速度快于消息传递,但是共享内存要避免内存冲突。在多处理器系统上,共享内存有高速缓存一致性的问题

共享内存

共享内存实现通信一定要面临一种情况:其中一个进程是消息的发送者,另一个进程是消息的接收者。

这样我们必须要设计算法保证:消息接受者知道消息发送者何时发送

生产者算法
while(true){while(((in+1)%BUFFER_SIZE)==out); //共享内存满了,就不能生产等待消费者进程拿buffer[in]=next_produced;in=(in+1))%BUFFER_SIZE
}
消费者算法
item next_consumed;
while(true){while(in==out);//此时共享内存是空的,无法拿东西next_comsumed=buffer[out];out=(out+1)%BUFFER_SIZE;

算法关键点: 

1、缓冲区最大值为BUFFER_SIZE-1(人为设定)

2、in+1==out设定为满,in==out设定为空

3、如果想要缓冲区最大值为BUFFER_SIZE,需要另设一个标志数用来记录缓冲区是满的还是空的。否则满的和空的都是in==out成立则无法区分

4、本质就是双指针实现,如上图所示

消息传递 

定义

关键点:

1、消息传递对于分布式环境(硬件不同)的两个进程的通信特别有用

2、消息传递必须通过系统调用完成,所以必须陷入内核

3、消息传递一共有两种通信方式,第一种是直接通信方式,第二种是间接通信方式

首先要知道一个消息是由消息头和消息体组成的,消息头里包括:发送进程ID、接收进程ID、消息类型、消息长度等格式化的信息(计算机网络中发送的“报文”其实就是一种格式化的消息)。

直接通信方式,如下:

发送进程把它想要发送的消息,通过发送原语发送给接收进程,然后这些消息会被放到接收进程的消息队列里面,接着接收进程通过接收原语一个个读取消息队列中的消息,这样发送进程和接收进程就实现了线程通信。

间接通信方式,如下:

对于间接通信方式,进程1会先通过发送原语把消息放到一个信箱中,然后进程2会通过接收原语从信箱中读取这些消息。

 算法实现

总结

本文到这里就结束啦~~这堂课的内容较为杂乱、复杂,但是学一学拓展一下知识是非常好的呀~~
如果觉得对你有帮助,辛苦友友点个赞哦~

知识来源:操作系统概念(黑宝书)、山东大学高晓程老师PPT及课上讲解。不要私下外传

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

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

相关文章

BD202311夏日漫步(最少步数,BFS或者 Dijstra)

本题链接&#xff1a;码蹄集 题目&#xff1a; 夏日夜晚&#xff0c;小度看着庭院中长长的走廊&#xff0c;萌发出想要在上面散步的欲望&#xff0c;小度注意到月光透过树荫落在地砖上&#xff0c;并且由于树荫的遮蔽度不通&#xff0c;所以月光的亮度不同&#xff0c;为了直…

【蓝桥杯】第十五届填空题a.握手问题

题解&#xff1a; 根据问题描述&#xff0c;总共有 50 人参加会议&#xff0c;每个人除了与自己以外的其他所有人握手一次。但有 7 个人彼此之间没有进行握手&#xff0c;而与其他所有人都进行了握手。 首先&#xff0c;计算所有人进行握手的总次数&#xff1a; 总人数为 50 …

每日OJ题_01背包③_力扣494. 目标和(dp+滚动数组优化)

目录 力扣494. 目标和 问题解析 解析代码 滚动数组优化代码 力扣494. 目标和 494. 目标和 难度 中等 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个 表达式 &#xff1a; …

AI论文速读 |(图腾) TOTEM:通用时间序列分析的token化时间序列嵌入表示

题目&#xff1a;TOTEM: TOkenized Time Series EMbeddings for General Time Series Analysis 作者&#xff1a;Sabera Talukder ; Yisong Yue ; Georgia Gkioxari 机构&#xff1a;加州理工学院&#xff08;Caltech&#xff09; 网址&#xff1a;https://arxiv.org/abs/24…

【DL水记】循环神经网络RNN的前世今生,Transformer的崛起,Mamba模型

文章目录 RNN网络简介传统RNN网络结构RNN的分类 长-短期记忆网络 (LSTM)GRU网络横空出世的Transformer网络Self-AttentionVisionTransformer Mamba模型Reference: RNN网络简介 “当人类接触新事物时&#xff0c;他们不会从头开始思考。就像你在阅读这篇文章时&#xff0c;你会根…

2024常见性能测试工具!

一&#xff1a;如何选择性能工具 选择性能测试工具时&#xff0c;可以从以下几个方面进行考虑&#xff1a; 1. 需求匹配&#xff1a;首先要明确项目的具体需求&#xff0c;比如需要测试的应用类型、协议、负载规模等。确保所选工具能够满足这些需求。 2. 技术兼容性&#xf…

MySQL进阶二

目录 1.使用环境 2.排序窗口函数 3.聚合窗口函数 1.使用环境 数据库&#xff1a;MySQL 8.0.30 客户端&#xff1a;Navicat 15.0.12 接续MySQL进阶一&#xff1a; MySQL进阶一-CSDN博客文章浏览阅读452次&#xff0c;点赞9次&#xff0c;收藏4次。MySQL进阶操作一。https…

科软24炸穿了,25还能冲吗?

25考研&#xff0c;科软必然保持大热 不是吧兄弟&#xff0c;明眼人都能看出来&#xff0c;科软以后不会出现大冷的局面了&#xff0c;除非考计算机的人减少&#xff0c;因为科软简直是叠满了buff&#xff0c;首先科软的专业课是22408&#xff0c;考的是数学二&#xff0c;这就…

Kubernetes 升级不弃 Docker:KubeKey 的丝滑之道

作者&#xff1a;尹珉&#xff0c;KubeSphere Ambaasador&Contributor&#xff0c;KubeSphere 社区用户委员会杭州站站长。 引言 随着 Kubernetes 社区的不断发展&#xff0c;即将迎来 Kubernetes 1.30 版本的迭代。在早先的 1.24 版本中&#xff0c;社区作出一个重要决策…

外贸公司应该怎么选择企业邮箱?哪个企业邮箱最好?

外贸公司业务的特殊性需要他们频繁进行跨国的沟通交流&#xff0c;那么外贸公司应该如何选择适合的企业邮箱呢&#xff1f;首先&#xff0c;传输邮件的稳定安全是前提&#xff0c;另外由于沟通多是国外客户&#xff0c;邮件的翻译也成为外贸公司企业邮箱的刚需。小编今天就详细…

C++ 之 【类与对象】从入门到精通一条龙服务 入门篇(类的定义,this指针。。。)

不要觉的自己很没用&#xff0c;其实你还可以给家人带来温暖&#xff0c;比如爸妈看到你就来火 目录&#xff1a; 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 四、类的访问限定符及封装 1.访问限定符 2.封装 五、类的作用域 六、类的实例化 七、类的…

27、链表-合并两个有序链表

思路&#xff1a; 这道题不需要集合放入两个链表再进行重排序&#xff0c;只需要两个指针&#xff0c;按大小进行遍历&#xff0c;代码如下&#xff1a; class Solution {/*** 1->3->5->7* 2->4->6->8->10->12* * 1->3->5->7* h c1* p* 2-…