进程对临界资源的互斥访问

临界资源与临界区

临界资源(critical resource):一次只能供一个进程使用的资源。   如:硬件有打印机等,软件有变量,磁盘文件(写入的时候)。

临界区(critical section):把进程中访问临界资源的那段代码成为临界区。

为了实现临界资源的互斥访问,只要做到进程互斥地进去自己的临界区,便可以实现进程对临界资源的互斥访问。

同步机制

为实现各进程互质地访问自己的临界区,操作系统需要同步机制来协调各进程的运行。

1、同步机制的规则

  (1)空闲让进:当无进程处于临界区,表明临界资源处于空闲状态,允许请求进去临界区的进程进去临界区

  (2)忙则等待:当有进程处于临界区,表明临界资源正在访问,其他请求进入临界区的进程必须等待。

  (3)有限等待:应使在等待的进程在有限的事件内进入自己的临界区,避免"死等"状态

  (4)让权等待:当进程不能进入自己的临界区,应立即释放处理机,以避免进入"忙等"状态

2、硬件同步机制

 为临界资源设置一把锁,当临界资源无进程使用时,锁是打开的,当临界资源正在被进程使用时,则锁是关闭的。

锁可能是一个布尔变量lock,初始时,lock = FALSE,那么每次访问临界资源时,都要进程锁测试。

bool lock = false;
    if(!lock)
    {
        lock = true;
        access critical section;//访问临界区资源
    }

但是在多任务的处理机中,可能会发生错误。假设有2个进程都要访问同一临界资源,进程a通过了锁测试,但是未将lock设为true时,发生了进程调度,进程b开始执行锁测试,同样通过了锁测试,从而使得两个进程访问同一个临界资源。

  (1)关中断:在进入锁测试之前关闭中断,直到完成锁测试并且上锁之后才打开中断。

  (2)利用Test-and-set指令:这是一条硬件指令,且该指令是原子操作(atomic operataion),原子操作指的是该执行过程要么不做,那么全做,即像原子一样不可分割。下面的TS就是一个原子操作,所以不会发生上面所说的问题。

bool TS(bool *lock)//lock 为临界资源的锁
{
    bool old ;
    old = lock;
    lock = true;//如果锁为true,那么这句不影响锁,如果锁为false,那么正好上锁
    return old;
}
while(TS(&lock));//循环测试直到TS(&lock) 为false
access critical section;
lock = false;

  (3)利用Swap指令:该指令也是硬件指令,且是原子操作。可以看出下面的代码其实思想是和上面的代码思想是一样的。只不过实现方式不同而已。

void swap(bool *a, bool *b)
{
    //如果a==true,那么swap语句不影响锁,如果a==false,那么正好上锁
    bool tmp
    tmp = *a;
    *a = *b;
    *b = tmp;
}
bool key = true;
do{
    swap(&lock,&key);
}while(key!=false)

3、信号量机制

时间: 2024-10-24 21:12:57

进程对临界资源的互斥访问的相关文章

用信号量解决进程的同步与互斥探讨【持续更新】

现代操作系统采用多道程序设计机制,多个进程可以并发执行,CPU在进程之间来回切换,共享某些资源,提高了资源的利用率,但这也使得处理并发执行的多个进程之间的冲突和相互制约关系成为了一道难题.如果对并发进程的调度不当,则可能会出现运行结果与切换时间有关的情况,令结果不可再现,影响系统的效率和正确性,严重时还会使系统直接崩溃.就比如你只有一台打印机,有两个进程都需要打印文件,如果直接让他们简单地并发访问打印机,那么你很可能什么都打印不出来或者打印的文件是...anyway,我们需要增加一些机制来控制并

计算机操作系统学习笔记_5_进程管理 -- 同步与互斥

h3.western { font-family: "Liberation Sans",sans-serif; }h3.cjk { font-family: "微软雅黑"; }h3.ctl { font-family: "AR PL UMing CN"; }h2.western { font-family: "Liberation Sans",sans-serif; font-size: 16pt; }h2.cjk { fon

Linux中四种进程或线程同步互斥控制方法

原文地址:http://blog.itpub.net/10697500/viewspace-612045/ 一.Linux中 四种进程或线程同步互斥的控制方法: 1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. 2.互斥量:为协调共同对一个共享资源的单独访问而设计的. 3.信号量:为控制一个具有有限数量用户资源而设计. 4.事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始. 二.临界区(Critical Section) 保证在某一时刻只有一个线程

浅析Redis实现lock互斥访问资源

Redis是当前很流行的一种开源键值数据库.目前睿思的后台架构在数据库层采用了Redis和MySQL组合的形式,其中Redis主要用来存储状态信息(比如当前种子的peer)和读写频繁的数据.Redis完全运行在内存之上,无lock设计,速度非常快!通过实测,在睿思服务器上读写速度达到3万次/s. 在高并发的应用中,很多时候我们需要对某些资源进行竞争访问,比如在很多人下载一个热门资源,就可能存在很多请求去修改某个资源的peer信息(就是保存了当前保种人的ip地址和端口号),需要保证某个请求修改pe

使用中断开关实现全局变量互斥访问

最近在STM32F429平台上实现一套主从机串口库,在开发过程中,出现偶发性丢帧问题,反复核对关键代码,均未发现任何问题,一筹莫展.按照经验第一反应就是互斥访问导致的脏数据问题,但苦于无法锁定问题,因为只有在串口大量数据收发时,才出现偶发性丢帧,无法采取在线调试锁定问题,极其难以抓取.为了能够尽快找到问题关键采取了最费力的办法: 锁定问题代码,对所有全局变量互斥访问代码逐一注释,同时检测注释后是否停止丢帧:锁定问题代码位置: 在问题代码处添加调试代码,通过串口重定向打印相关全局变量: 虽然方法费

C++中四种进程或线程同步互斥的控制方法

现在流行的进程线程同步互斥的控制机制,其实是由最原始最基本的4种方法实现的.由这4种方法组合优化就有了.Net和Java下灵活多变的,编程简便的线程进程控制手段. 这4种方法具体定义如下 在<操作系统教程>ISBN 7-5053-6193-7 一书中能够找到更加周详的解释 1临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. 2互斥量:为协调一起对一个共享资源的单独访问而设计的. 3信号量:为控制一个具备有限数量用户资源而设计. 4事 件:用来通知线程有一些事件已

四种进程或线程同步互斥的控制方法

1.临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问. 临界区(Critical Section)EnterCriticalSection() 进入临界区 LeaveCriticalSection() 离开临界区 EnterCriticalSection() 语句执行后代码将进入临界区以后无论发生什么,必须确保与之匹配的 LeaveCriticalSection()都能够被执行到.否则临界区保护的共享资源将永远不会被释放.虽然临界区同步速度很快,但却只能用来同步本

单实例模式和互斥访问

场景说明:在实际的应用开发中,很多人没有注意到一点:在生成单实例的过程中,如果由线程去创建对象的实例,有可能在第一次检测到对象不存在的情况下,准备创建对象,此时由于多线程的缘故,恰巧当前线程被挂起,另一个线程同样执行到这个语句,于是创建一个对象,另一个线程冲睡眠中被唤醒,于是执行了创建对象,现在就有两个对象,完全背离了单实例的设计模式, 解决方法: 1)在主线程还没有创建多线程的时候,创建单实例,但是这里有一个问题:就不会达到延时加载的效果,变成了急剧加载,也就是说预先加载了对象,可能这个对象根

win7结束进程 时,提示“拒绝访问”、“没有此任务的实例运行”怎么办?

开发了个程序,创建了一个进程,但是杀不掉了,在任务管理器里面 右键--结束进程,提示"拒绝访问",或者"没有此任务实例运行" 怎么办? 直接给答案:PCHunter 具体方法: 1.打开PCHunter,在进程选项卡下面可以找到无法结束的进程,右键--强制结束,失败(这儿效果跟任务管理器下的结束时一样的) 2.这时候 右键--查看进程线程 ,然后将所有的线程给杀光光,再出来到进程选项卡下结束进程,OK 我用了整整一天半才实现,这一天半我杀不掉进程重启电脑十几次,哎