信号量

进程执行模式与进程间通讯

孤街浪徒 提交于 2019-12-15 03:05:26
执行模式 指令分为 特权指令 (只能由操作系统内核使用的指令)和 非特权指令 (只能由用户程序使用的指令),因为指令有特权和非特权之分,所以 CPU 也分为 2 种执行模式: 系统态 (可以执行所有指令,使用所有资源以及改变 CPU 状态)和 用户态 (只能执行非特权指令)。 CPU 的系统态和用户态之间的切换。 进程间通讯 当进程之间需要数据传输、共享数据时,进程间就需要互相通讯,通讯方式有如下几种,这里只是简单概括一下,不展开讲,咱的重点在于多线程,进程咱们简单了解一下就可以,感兴趣的同学可以根据要点进行深入学习。 管道(Pipe) 管道是半双工通讯,数据是单向流动,要建立进程间互相通讯,则需要 2 个管道,这种通讯方式只能在亲戚关系的进程间使用,比如父子进程。 流管道(Flow Pipe) 流管道是管道进化来的,数据不再是单向流动,可以双向流动,但是依旧是只能在亲戚关系的进程间使用。 有名管道(Named Pipe) 有名管道提供了新的功能,就是给管道设置名字,它改善了上面 2 种管道通讯方式,支持了非亲戚关系的进程通讯。 信号量(Semophore) 信号量相当于计数器,利用它来控制多个进程访问共享资源,当一个进程A在访问共享资源时,信号量防止其他进程来访问,只有当进程A不访问共享资源了,其他进程才能访问。 信号(Signal) 信号可以在任何时候发给某一进程

进程之间究竟有哪些通信方式?如何通信?

旧街凉风 提交于 2019-12-14 01:49:35
进程之间究竟有哪些通信方式?如何通信? 1、管道 我们来看一条 Linux 的语句 1 | netstat - tulnp | grep 8080 学过 Linux 命名的估计都懂这条语句的含义,其中”|“是管道的意思,它的作用就是把前一条命令的输出作为后一条命令的输入。在这里就是把 netstat -tulnp 的输出结果作为 grep 8080 这条命令的输入。如果两个进程要进行通信的话,就可以用这种管道来进行通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信方式称之为匿名管道。 并且这种通信方式是单向的,只能把第一个命令的输出作为第二个命令的输入,如果进程之间想要互相通信的话,那么需要创建两个管道。 居然有匿名管道,那也意味着有命名管道,下面我们来创建一个命名管道。 1 | mkfifo test 2 | 这条命令创建了一个名字为 test 的命名管道。 接下来我们用一个进程向这个管道里面写数据,然后有另外一个进程把里面的数据读出来。 1 | echo "this is a pipe" > test / / 写数据 这个时候管道的内容没有被读出的话,那么这个命令就会一直停在这里,只有当另外一个进程把 test 里面的内容读出来的时候这条命令才会结束。接下来我们用另外一个进程来读取 1 | cat < test / / 读数据 我们可以看到,test

ucore lab 7

自古美人都是妖i 提交于 2019-12-11 17:50:51
OS ucore lab 7 练习零: 填写已有实验: 复制以下文件 其中 trap.c 需要进行修正 vmm.c trap.c default_pmm.c pmm.c proc.c swap_fifo.c trap.c: static void trap_dispatch(struct trapframe *tf) { ++ticks; /** 注销掉下面这一句 因为这一句被包含在了 run_timer_list() run_timer_list() 在之前的基础上 加入了对 timer 的支持 ***/ // sched_class_proc_tick(current); run_timer_list(); } 练习一:理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码)   完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件)个人完成的lab6和练习0完成后的刚修改的lab7之间的区别,分析了解lab7采用信号量的执行过程。执行make grade,大部分测试用例应该通过。 请在实验报告中 Q1: 给出内核级信号量的设计描述,并说其大致执行流流程。 Q2:请在实验报告中给出给用户态进程/线程提供信号量机制的设计方案,并比较说明给内核级提供信号量机制的异同。 Q1: // 先是定义了一个信号量的数据结构 typedef struct { int

解决灾难性雪崩效应的五种方式

∥☆過路亽.° 提交于 2019-12-11 07:38:46
学习主题:Hystrix 学习目标: 1.解决灾难性雪崩效应-服务熔断-服务熔断处理 (1)熔断参数circuitBreaker.enabled的作用是什么? 是否开启熔断 (2)熔断参数circuitBreaker.requestVolumeThreshold的作用是什么? 一个统计窗口内熔断触发的最小个数/10s (3)熔断参数circuitBreaker.sleepWindowInMiliseconds的作用是什么? 熔断多少秒后去尝试请求 (4)熔断参数circuitBreaker.errorThresholdPercentage的作用是什么? 失败率达到多少百分比后熔断 (5)熔断参数circuitBreaker.forceOpen的作用是什么? 是否强制开启熔断 (6)熔断参数circuitBreaker.forceClosed的作用是什么? 是否强制关闭熔断 2.解决灾难性雪崩效应-隔离机制-线程池隔离-创建项目 (1)什么是线程池隔离? 是一种依赖隔离技术 (2)线程池隔离的优点是什么? 1、用用线程池隔离可以完全隔离依赖的服务,请求线程县城可以快速放回; 2、当线程池出现问题时,线程池隔离是独立的,不会影响其他服务和接口; 3、当失败的服务再次变得可用时,线程池将清理并可立即回复,而不需要一个长时间的恢复; 4、独立的线程池提高了并发性。 (3

C#线程学习笔记六:线程同步--信号量和互斥体

拈花ヽ惹草 提交于 2019-12-10 23:47:22
本笔记摘抄自: https://www.cnblogs.com/zhili/archive/2012/07/23/Mutex_And_Semaphore.html ,记录一下学习过程以备后续查用。 一、信号量(Semaphore) 信号量(Semaphore)是由内核对象维护的int变量。当信号量为0时,在信号量上等待的线程会堵塞;信号量大于0时,就解除堵塞。当在一个信号量上等待 的线程解除堵塞时,内核自动会将信号量的计数减1。在.NET下通过Semaphore类来实现信号量同步。 Semaphore类 限制可同时访问某一资源或资源池的线程数。 线程通过调用 WaitOne方法将信号量减1,并通过调用Release方法把信号量加1。 先说下构造函数: public Semaphore(int initialCount,int maximumCount);通过两个参数来设置信号的初始计数和最大计数。 下面代码演示信号量同步的使用: class Program { //共享资源 public static int number = 0; //初始信号量计数为0,最大计数为10。 public static Semaphore semaphore = new Semaphore(0, 10); static void Main(string[] args) { #region 线程同步

线程笔记

允我心安 提交于 2019-12-10 14:06:03
1.sleep 和 wait都可以让线程等待若干时间。但是wait可以被唤醒,而且wait会释放锁资源,但是sleep不会。 wait 后调用notify可以通知wait这个锁的所有线程,去竞争这个锁(在当前线程释放掉锁之后)----配合synchronized使用 线程的挂起和继续执行: suspend(挂起)resume(继续执行)被挂起的线程必须等到 继续执行指令后才继续执行,但是这两个方法已经废弃,因为挂起时他们不会释放锁资源。 等待线程结束(join) 和线程谦让(yield) 很多时候一个线程的执行,需要依赖于另一个线程的结果,这时候,这个线程就需要等待依赖线程执行完毕,这个操作就是join: join可以设置等待的最大时间 调用方法为:希望某个线程对象执行完毕再执行别的线程(主线程或者其他线程)的方法,则目标线程.join(); 线程礼让:yield()它会让当前线程让出CPU,让出CPU后重新进行CPU资源竞争(他自己也会参与),其实礼让就是我让出资源然后大家重新再次一起抢。 5.重入锁的实现: 原子状态:使用CAS操作,来存储 当前锁的状态,判断锁是否已经被别的线程持有 等待队列:所有没有请求到锁的线程会进入等待队列进行等待。待有线程释放锁后,系统就能从等待队列中唤醒一个线程,继续工作。 阻塞原语park()和unpark(),用来挂起和恢复线程

操作系统-----第二章 进程管理

半城伤御伤魂 提交于 2019-12-10 10:59:13
第二章 进程管理 文章目录 第二章 进程管理 @[toc] 1. 进程的定义 (1). PCB (2). 进程的组织 1). 链接方式 2). 索引方式 (3). 进程的特性 2. 进程状态和转换 (1). 进程的三种基本状态: (2). 另外两种状态: (3). 状态的转换 3. 进程控制 4. 进程通信 (1). 共享存储 1). 基于数据结构的共享 2). 基于存储区的共享 (2). 管道通信 (3). 消息传递 1). 直接通信方式 2). 间接通信方式 5. 线程 (1). 线程的概念 (2). 线程的实现方式 (3). 多线程模型 6. 处理机调度 (1). 高级调度 (2). 中级调度 (3). 线程状态的七状态模型 (4). 低级调度 (5). 联系和对比 7. 进程调度 (1). 进程调度的时机 (2). 进程调度的方式 (3). 调度算法的评价指标 (4). 调度算法 1). 先来先服务(FCFS) 2). 短作业优先(SJF) 3). 高响应比优先(HRRN) 4). 时间片轮转(RR) 5). 优先级调度算法 6). 多级反馈队列 8. 实现进程互斥 (1). 软件实现 1). 单标志法 2). 双标志先检查法 3). 双标志后检查法 4). Peterson算法 (2). 硬件实现 1). 中断屏蔽 2). TestAndSet指令 3). Swap指令

互斥量与信号量

99封情书 提交于 2019-12-10 06:16:33
互斥量(Mutex) 互斥量表现互斥现象的数据结构,也被当作二元信号灯。一个互斥基本上是一个多任务敏感的二元信号,它能用作同步多任务的行为,它常用作保护从中断来的临界段代码并且在共享同步使用的资源。 Mutex 本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别代表了 Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程可以 Lock临界资源,之后Mutex值减1变为0。 Mutex可以被抽象为四个操作: - 创建 Create - 加锁 Lock - 解锁 Unlock - 销毁 Destroy Mutex被创建时可以有初始值,表示Mutex被创建后,是锁定状态还是空闲状态。在同一个线程中,为了防止死锁,系统不允许连续两次对Mutex加锁(系统一般会在第二次调用立刻返回)。也就是说,加锁和解锁这两个对应的操作,需要在同一个线程中完成。 不同操作系统中提供的Mutex函数: 动作\系统 Win32 Linyx Solaris 创建 CreateMutex pthread_mutex_init mutex_init 加锁 WaitForSingleObject pthread_mutex

二元信号量、互斥量和临界区之间的区别

☆樱花仙子☆ 提交于 2019-12-10 04:05:52
二元信号量   是最简单的一种锁,适合只能被唯一一个线程独占访问的资源;对于允许多个线程并发访问的资源,多元信号量简称信号量; 互斥量   和二元信号量很类似,资源仅同时允许一个线程访问,但和信号量不同的是,信号量在整个系统可以被任意线程获取并释放;也就是说哪个线程锁的,要哪个线程解锁。 临界区    是比互斥量更加严格的同步手段。在术语中,把临界区的获取称为进入临界区,而把锁的释放称为离开临界区。与互斥量和信号量的区别:   (1)互斥量和信号量字系统的任何进程都是可见的。   (2)临界区的作用范围仅限于本进程,其他进程无法获取该锁。    来源: https://www.cnblogs.com/bugutian/p/5087538.html

进程通信和同步(转)

ぃ、小莉子 提交于 2019-12-09 21:24:53
概念 竞争条件 多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时许,称为竞争条件。 忙等待的互斥 几种实现互斥的方案: 屏蔽中断 1在单处理器系统中,最简单的方法是使每个进程在刚刚进入临界区后立即屏蔽所有中断,包括时钟中断。CPU 只有在发生中断的时候才会进行进程切换,这样在中断被屏蔽后 CPU 将不会被切换到其他进程。 锁变量 严格轮换法 while (TRUE) { while (turn != 0) critical_region(); turn = 1; noncritical_region(); } while (TRUE) { while (turn != 1) critical_region(); turn = 0; noncritical_region(); } 忙等待检查变量。使用忙等待的锁称为自旋锁。 Peterson 解法 #define FALSE 0 #define TRUE 1 #define N 2 /* number of processes */ int turn; /* whose turn is it? */ int interested[N]; /* all values initially 0 (FALSE) */ void enter_region(int process); /* process is 0 or 1 */ {