临界区

spin_lock spin_lock_irq spin_lock_irqsave

我只是一个虾纸丫 提交于 2019-12-05 16:50:25
1,为啥需要自旋锁 很多时候我们并不能采用其他的锁,比如读写锁、互斥锁、信号量等。一方面这些锁会发生上下文切换,他的时间是不可预期的,对于一些简单的、极短的临界区完全是一种性能损耗;另一方面在中断上下文是不允许睡眠的,除了自旋锁以外的其他任何形式的锁都有可能导致睡眠或者进程切换,这是违背了中断的设计初衷,会发生不可预知的错误。基于两点,我们需要自旋锁,他是不可替代的。 2,为啥自旋锁禁止抢占 这一点其实很好理解,当一个 CPU 获取到一把自旋锁之后,开始执行临界区代码,此时假设他的时间片运转完毕,进程调度会主动触发调度将其调走,执行另一个线程/进程,结果恰巧了这个线程/进程也需要用到该自旋锁,而上一个线程/进程还在停留在临界区内未释放锁,导致本进程无法获取到锁而形成死锁,所以自旋锁为了规避此类情形的出现从而直接禁止对已经开始运行的临界区设置禁止抢占标志。 3,为什么临界区禁止睡眠 如果自旋锁锁住以后进入睡眠,而此时又不能进行处理器抢占,内核的调取器无法调取其他进程获得该 CPU,从而导致该 CPU 被挂起;同时该进程也无法自唤醒且一直持有该自旋锁,进一步会导致其他使用该自旋锁的位置出现死锁。 4,spin_lock 系列的分别 每一种锁出现都有自己的原因,spin_lock 系列的锁就是为了解决这一个又一个的问题才会新增的各种自旋锁变种,这也符合现代计算机代码设计逻辑

Lab7:同步互斥

。_饼干妹妹 提交于 2019-12-05 07:30:37
并发进程的正确性 独立进程 不和其他进程共享资源或状态 确定性 -> 输入状态决定结果 可重现 -> 能够重现起始条件 调度顺序不重要 并发进程 在多个进程间有资源共享 不确定性 不可重现 并发进程的正确性 执行过程是不确定性和不可重现的 程序错误可能是间歇性发生的 并发的好处 共享资源 加速 模块化 同步问题 时间 A B 3:00 查看冰箱,没有面包 3:05 离开家去商店 3:10 到达商店 查看冰箱,没有面包了 3:15 购买面包 离开家去商店 3:20 到家,把面包放进冰箱 到达商店 3:25 购买面包 3:30 到家,把面包放进冰箱 解决 利用两个原子操作实现一个锁(lock) Lock.Acquire() 在锁被释放前一直等待,然后获得锁 如果两个线程都在等待同一个锁,并且同时发现锁被释放了,那么只有一个能够获得锁 breadlock.Acquire(); //进入临界区 if (nobread) { buy bread; //临界区 } breadlock.Release(); //退出临界区 进程的交互关系:相互感知程度 相互感知的程度 交互关系 进程间的影响 相互不感知(完全不了解其它进程的存在) 独立 一个进程的操作对其他进程的结果无影响 间接感知(双方都与第三方交互,如共享资源) 通过共享进行协作 一个进程的结果依赖于共享资源的状态 直接感知(双方直接交互

java synchronized 探究

浪子不回头ぞ 提交于 2019-12-04 20:18:45
java synchronized关键字是并发编程最常用的工具,也是最重要的工具之一。今天来探究下其含义 写两个类,两段不同的临界区代码进行测试。 有以下4种测试方案,每种方案对应4种不同的锁类型:对象锁: synchronized(this),本类锁: synchronized(Me.class),父类锁: synchronized(Parent.class),自定义锁对象   1. 同一个对象,在不同线程中运行   2. 同一个类的不同对象,在不同线程中运行   3. 不同类(有共同的父类)的不同对象,在不同线程中运行   4. 不同类(没有共同的父类)的不同对象,在不同线程中运行 测试结果:   用对象锁,只有1可以互斥访问临界区;   用本类锁,则1和2可以互斥访问临界区;   用共同父类的锁,全部都可以互斥访问临界区。(注意,使用第4种测试方案时,两个对象已经没有共同的父类了,因此这个所谓共同父类的锁,其实是一个第3者,与这两个类没有直接关系,类似于自定义的锁对象,只不过这个自定的锁对象不是普通的对象,而是一个Class对象)   用自定义的锁对象,全部都可以互斥访问临界区。 /** * synchronized关键字测试 * * @author zhangxz * @date 2019-11-18 11:07 */ public class

Delphi线程同步(临界区、互斥、信号量)

限于喜欢 提交于 2019-12-04 09:14:31
转载自: https://www.cnblogs.com/xumenger/p/4450659.html 当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源。   例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件的字符数。当然,在整个文件调入内存之前,统计它的计数是没有意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当做是互不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为解决此问题,你必须使两个线程同步工作   存在一些线程同步地址的问题,Win 32 提供了许多线程同步的方式。这里将会讲到:临界区、互斥、信号量和事件   为了检验这些技术,首先来看一个需要线程同步解决的问题。假设有一个整数数组,需要按照升序赋初值。现在要在第一遍把这个数组赋初值为1~128,第二遍将此数组赋初值为128~255,然后结果显示在列表中。要用两个线程来分别进行初始化。下面的代码给出了没有做线程同步的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

解决原子性问题?脑海中有这个模型就可以了

匿名 (未验证) 提交于 2019-12-03 00:11:01
上一篇文章 可见性有序性,Happens-before来搞定 ,解决了并发三大问题中的两个,今天我们就聊聊如何解决原子性问题 原子性问题的源头就是 线程切换 ,但在多核 CPU 的大背景下,不允许线程切换是不可能的,正所谓「魔高一尺,道高一丈」,新规矩来了: 互斥: 同一时刻只有一个线程执行 实际上,上面这句话的意思是: 对共享变量的修改是互斥的,也就是说线程 A 修改共享变量时其他线程不能修改,这就不存在操作被打断的问题了,那么如何实现互斥呢? 对并发有所了解的小伙伴马上就能想到 锁 这个概念,并且你的第一反应很可能就是使用 synchronized,这里列出来你常见的 synchronized 的三种用法: public class ThreeSync { private static final Object object = new Object (); public synchronized void normalSyncMethod (){ //临界区 } public static synchronized void staticSyncMethod (){ //临界区 } public void syncBlockMethod (){ synchronized ( object ){ //临界区 } } } 三种 synchronized 锁的内容有一些差别:

进程互斥的要求与实现方法

匿名 (未验证) 提交于 2019-12-02 23:49:02
临界资源:进程独占型的硬件和共享的数据结构和文件。临界区:使用临界资源的程序段。 要求: 实现方法: 软件 :通过全局变量来控制程序执行,但是程序在检测标志变量后,修改标志变量前发生中断,然会有多个进程进入临界区。 硬件: 关闭总中断 将软件的方法使用机器指令封装好,然后再调用,解决了因中断导致的错误。但是会有忙等现象。 机器指令包括:test&set 以及exchange 信号量 信号量是一个信号灯一样的结构体变量,其成员包括:一个整型变量和一个队列。 使用wait和signal指令,wait指令申请资源,signal指令释放资源。 将暂时不能执行的程序放入阻塞队列。(这样解决了忙等问题) 管程 消息传递 文章来源: https://blog.csdn.net/li15528180102/article/details/96475871

win32API多线程编程

蹲街弑〆低调 提交于 2019-12-02 19:12:38
win32线程API 在Windows平台下可以通过Windows的线程库来实现多线程编程。 对于多线程程序可以使用Visual Studio调试工具进行调试,也可以使用多核芯片厂家的线程分析调试工具进行调试。 Win32 API(了解Windows,代码小,效率高) Windows操作系统为内核以及应用程序之间提供的接口 将内核提供的功能进行函数封装 应用程序通过调用相关的函数获得相应的系统功能 _beginthread _beginthread(函数名,栈大小,参数指针) Win32 函数库中提供了操作多线程的函数, 包括创建线程、管理线程、终止线程、线程同步等接口。 线程函数(线程开始执行的函数) DWORD WINAPI ThreadFunc (LPVOID lpvThreadParm ); 线程创建 HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 第一个参数lpThreadAtt,是一个指向SECURITY- ATTRIBUTES结构的指针

win32API多线程编程

烂漫一生 提交于 2019-12-02 19:00:14
win32线程API 在Windows平台下可以通过Windows的线程库来实现多线程编程。 对于多线程程序可以使用Visual Studio调试工具进行调试,也可以使用多核芯片厂家的线程分析调试工具进行调试。 Win32 API(了解Windows,代码小,效率高) Windows操作系统为内核以及应用程序之间提供的接口 将内核提供的功能进行函数封装 应用程序通过调用相关的函数获得相应的系统功能 _beginthread _beginthread(函数名,栈大小,参数指针) Win32 函数库中提供了操作多线程的函数, 包括创建线程、管理线程、终止线程、线程同步等接口。 线程函数(线程开始执行的函数) DWORD WINAPI ThreadFunc (LPVOID lpvThreadParm ); 线程创建 HANDLE CreateThread ( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 第一个参数lpThreadAtt,是一个指向SECURITY- ATTRIBUTES结构的指针

计算机操作系统第二章测试题及答案

霸气de小男生 提交于 2019-12-02 10:06:27
题目 1 of 28 1.0/ 1.0 得分 下列的进程状态变化中,( )变化是不可能发生的。 A. 等待→执行 B. 等待→就绪 C. 执行→等待 D. 执行→就绪 答案: A 反馈: 等待→执行 题目 2 of 28 1.0/ 1.0 得分 用P、V操作管理临界区时,信号量的初值应定义为( )。 A. 任意值 B. 1 C. 0 D. -1 答案: B 反馈: 1 题目 3 of 28 1.0/ 1.0 得分 分配到必要的资源并获得处理机时的进程状态是( )。 A. 执行状态 B. 就绪状态 C. 阻塞状态 D. 撤消状态 答案: A 反馈: 执行状态 题目 4 of 28 1.0/ 1.0 得分 下面对进程的描述中,错误的是( )。 A. 进程是指令的集合 B. 进程是动态的概念 C. 进程是有生命期的 D. 进程执行需要处理机 答案: A 反馈: 进程是指令的集合 题目 5 of 28 1.0/ 1.0 得分 在操作系统中,进程是一个具有一定独立功能的程序在某个数据集上的一次( )。 A. 运行活动 B. 等待活动 C. 单独操作 D. 关联操作 答案: A 反馈: 运行活动 题目 6 of 28 1.0/ 1.0 得分 P、V操作是( )。 A. 两组不同的机器指令 B. 两条高级进程通信原语 C. 两条低级进程通信原语 D. 两条系统调用命令 答案: C 反馈:

操作系统第四章思考题与练习题

筅森魡賤 提交于 2019-12-02 06:53:21
1、何谓之与时间有关的错误?举例说明之。并发进程执行时一定会产生与时间有关的错误吗?为什么。 与时间有关的错误是指两个程序都以各自的速度交叉着运行,同时访问共享信息导致的错误。 比如程序A对共享变量p执行+1操作后,休眠一秒输出变量p,程序B对共享变量p执行减1操作后,休眠一秒输出变量p。导致的结果就会和想象中的不相同。 并发程序不一定都导致时间相关的错误,我们可以对共享变量加锁来解决这个问题 2、什么是临界区,什么是相关临界区,对相关临界区的使用规则? 系统中某些资源一次只允许一个进程使用,则这类资源被称为临界资源,而在进程中访问临界资源的程序被称为临界区。 多个进程涉及到同一个临界资源的临界区被称为相关临界区。 使用规则:1、只能选择一个进程进入临界区,其他进程必须等待。 2、 不能强迫一个进程无限的等待进入他的临界区 3、任何一个进程在进入临界区后都要在有限的时间内退出临界区。 3、若使用P、V操作管理某一组相关临界区,其信号量S的值在【-1,1】之间变化,当S=-1,s=0,S=1时,他们各自的物理含义是什么? 当S=-1,临界区已满,且有一个进程正在等待 当S=0,临界区已满 当S=1, 临界区为空 4、两个并发执行的进程A和B的程序如下: 进程A: While(true){ N = N+5; }; 进程B: While(true){ 打印N的值; N = 0; };