• 进程同步算法


    进程的组成

    进程由以下内容组成:
    PCB:进程控制块,是进程的唯一标识
    程序,数据区,工作区

    进程的三态

    运行态,就绪态,阻塞态

    进程之间的互斥

    多个进程因争用临界资源而互斥执行,叫做进程间的互斥。实现进程互斥的方法有以下几种:

    • Dekker算法:这种算法需要设置一个整型变量turn,用来指示允许进入临界区的线程,turn=1表示P1可以进入临界区,turn=2表示P2可以进入临界区。还要设置一个flag[2]数组表示自己是否愿意进入临界区。flag[0]=true表示进程P1愿意进入临界区,为false表示不愿意进入临界区,flag[1]与P2对应。Dekker算法采用竞争的方式来进入临界区,假如P1想进入临界区,它将自己的flag[0]=true,然后看P2是否愿意进入临界区,如果P2不愿意,那么P1直接进入临界区。如果P2也愿意进入临界区,那么查看turn的值,看当前轮到谁进入临界区了。如果轮到P2进入临界区了,那么P1则表示自己不愿意进入临界区(flag[0]=flase)。将进入临界区权限让给P2.然后一直等P2从临界区退出。

    示例代码

    void P0()
    {
    	while(true)
    	{
    		flag[0] = true;//P0想使用关键区。
    		while(flag[1])//检查P1是不是也想用?
    		{
    			if(turn == 1)//如果P1想用,则查看P1是否具有访问权限?
    			{
    				flag[0] = false;//如果有,则P0放弃。
    				while(turn == 1);//检查turn是否属于P1。
    				flag[0] = true;//P0想使用。
    			}
    		}
    		visit(0); //访问Critical Partition。
    		turn = 1; //访问完成,将权限给P1。
    		flag[0] = false;//P0结束使用。
    	}
    }
    void P1()
    {
    	while(true)
    	{
    		flag[1] = true; //P1想使用关键区。
    		while(flag[0]) //检查P0是不是也想用?
    		{
    			if(turn == 0) //如果P0想用,则查看P0是否具有访问权限?
    			{
    				flag[1] = false; //如果有,则P1放弃。
    				while(turn == 0); //检查turn是否属于P1。
    				flag[1] = true; // P1想使用。
    			}
    		}
    		  visit(1); //访问Critical Partition。
    		turn = 0; //访问完成,将权限给P0。
    		flag[1] = false; //P1结束使用。
    	}
    }
    
    • Peterson算法:这种算法与Dekker算法很相似,但是采用谦让的态度。turn和flag[2]都少不了,而且其含义与Dekker算法一样。先表示自己愿意进入临界区,然后将进入临界区的权限让给对方。

    示例代码

    void procedure0()
    {
    	while(true)
    	{
    		flag[0] = true;
    		turn = 1;  //将进入临界区权限让给对方
    		while(flag[1] && turn == 1)
    		{
    			sleep(1);
    			printf("procedure0 is waiting!
    ");
    		}
    		//进入临界区
    		flag[0] = false;
    	}
    }
    void procedure1()
    {
    	while(true)
    	{
    		flag[1] = true;
    		turn = 0;
    		while(flag[0] && turn == 0)
    		{
    			sleep(1);
    			printf("procedure1 is waiting!
    ");
    		}
    		//进入临界区
    		flag[1] = false;
    	}
    }
    

    这两种算法都会出现忙等待现象,造成资源的浪费。

    硬件方法:“开关中断”指令,“交换”指令,“测试与设置”指令,这三种需要CPU指令集的支持,来达到互斥的目的。

    进程的同步

    进程之间的同步一般使用信号量来实现,P操作获取资源,V操作释放资源。下面是生产者--消费者模型。P1和P2共享缓冲区,S1和S2的初值为1和0。缓冲区满则不能放物品,缓冲区空不能拿物品。缓冲区只能放一件物品。

    P1进程

    while(true) {
    	生产一件产品;
    	P(S1); /*申请空缓冲区*/
    	放入物品;
    	V(S2);
    }
    

    P2进程

    while(true) {
    	P(S2); /*申请满缓冲区*/
    	获取物品;
    	V(S1);
    }
    

    P操作会消耗资源,V操作会释放资源。S>0时表示同类资源可用数量,S=0表示无可用资源,S<0时,S的绝对值表示正在被阻塞的进程数量。

    进程与线程

    进程是资源分配的单位,线程是调用的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(寄存器,栈,程序计数器),它与同一个进程的其他线程共享进程所拥有的全部资源。线程的切换相比于进程来说开销更小(切换时换入换出的内容比进程要小的多,所以速度快)。

    死锁产生的必要条件

    • 互斥资源的使用(资源独占):自己占有了资源,其它进程就无法共享使用
    • 不可剥夺:自己占有的资源不能被剥夺,直到主动释放为之
    • 零散请求:不能一次性将所有资源拿到手
    • 循环等待:等待资源的进程形成一个环

    只要破坏上面的一个条件就不会发生死锁。这是从预防的角度出发,即对资源的申请加以严格的限制,从而不会发生死锁。

    死锁的避免

    死锁的避免是在进程申请资源之前,看预判一下,满足进程的要求后会不会发生死锁。如果会发生则不分配,如果不发生则分配资源。

    单银行家算法

    在某一时刻,系统的某种资源(这里是资金)剩余4,这时有四个进程都要申请这种资源,则应将资源分给a或b让其执行。a或b执行后会释放自己占有的资源,这样其它进程可以继续执行了。

    多银行家算法

    单银行家算法是对单个资源的分发控制,而多银行家算法则控制多个资源。

    图a中表示每个进程总共要申请的资源数,图b表示每个进程已经申请到的资源,图c表示每个进程还需要申请的资源。然后给出分配策略。

  • 相关阅读:
    declare set声明注意
    Winform 的dadagridview控件的修改操作
    VS2010,VS2008,VS2005;工程之间的转换
    C#程序跨平台?
    上网黑色护眼,设置浏览器黑色风格
    AutoCompleteSource从文件里读取自动填充内容
    两个checkbox的控件控制操作只能选其一
    《博客园精华集CLR/C#分册》第三轮筛选结果 转载
    TransactSQL 示例 查询某个数据库内的所有表的记录行数及其总和
    EF 4.1中内部经常提交的 exec sp_reset_connection 的用途原来是为了重用池中的连接
  • 原文地址:https://www.cnblogs.com/xidongyu/p/6559625.html
Copyright © 2020-2023  润新知