zoukankan      html  css  js  c++  java
  • 2013.7.30 作业

    1.什么是死锁,怎么解决死锁

    产生死锁的必要条件:

    〈1〉互斥条件。即某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。这种独占资源如CD-ROM驱动器,打印机等等,必须在占有该资源的进程主动释放它之后,其它进程才能占有该资源。这是由资源本身的属性所决定的。如独木桥就是一种独占资源,两方的人不能同时过桥。

        〈2〉不可抢占条件。进程所获得的资源在未使用完毕之前,资源申请者不能强行地从资源占有者手中夺取资源,而只能由该资源的占有者进程自行释放。如过独木桥的人不能强迫对方后退,也不能非法地将对方推下桥,必须是桥上的人自己过桥后空出桥面(即主动释放占有资源),对方的人才能过桥。

        〈3〉占有且申请条件。进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻塞;但是,它在等待新资源之时,仍继续占用已占有的资源。还以过独木桥为例,甲乙两人在桥上相遇。甲走过一段桥面(即占有了一些资源),还需要走其余的桥面(申请新的资源),但那部分桥面被乙占有(乙走过一段桥面)。甲过不去,前进不能,又不后退;乙也处于同样的状况。

        〈4〉循环等待条件。存在一个进程等待序列{P1,P2,...,Pn},其中P1等待P2所占有的某一资源,P2等待P3所占有的某一源,......,而Pn等待P1所占有的的某一资源,形成一个进程循环等待环。就像前面的过独木桥问题,甲等待乙占有的桥面,而乙又等待甲占有的桥面,从而彼此循环等待。

      上面我们提到的这四个条件在死锁时会同时发生。也就是说,只要有一个必要条件不满足,则死锁就可以排除。

    死锁的预防:

      前面介绍了死锁发生时的四个必要条件,只要破坏这四个必要条件中的任意一个条件,死锁就不会发生。这就为我们解决死锁问题提供了可能。一般地,解决死锁的方法分为死锁的预防,避免,检测与恢复三种(注意:死锁的检测与恢复是一个方法)。我们将在下面分别加以介绍。

      死锁的预防是保证系统不进入死锁状态的一种策略。它的基本思想是要求进程申请资源时遵循某种协议,从而打破产生死锁的四个必要条件中的一个或几个,保证系统不会进入死锁状态。

       〈1〉打破互斥条件。即允许进程同时访问某些资源。但是,有的资源是不允许被同时访问的,像打印机等等,这是由资源本身的属性所决定的。所以,这种办法并无实用价值。

       〈2〉打破不可抢占条件。即允许进程强行从占有者那里夺取某些资源。就是说,当一个进程已占有了某些资源,它又申请新的资源,但不能立即被满足时,它必须释放所占有的全部资源,以后再重新申请。它所释放的资源可以分配给其它进程。这就相当于该进程占有的资源被隐蔽地强占了。这种预防死锁的方法实现起来困难,会降低系统性能。    

        〈3〉打破占有且申请条件。可以实行资源预先分配策略。即进程在运行前一次性地向系统申请它所需要的全部资源。如果某个进程所需的全部资源得不到满足,则不分配任何资源,此进程暂不运行。只有当系统能够满足当前进程的全部资源需求时,才一次性地将所申请的资源全部分配给该进程。由于运行的进程已占有了它所需的全部资源,所以不会发生占有资源又申请资源的现象,因此不会发生死锁。但是,这种策略也有如下缺点:

    (1)在许多情况下,一个进程在执行之前不可能知道它所需要的全部资源。这是由于进程在执行时是动态的,不可预测的;

    (2)资源利用率低。无论所分资源何时用到,一个进程只有在占有所需的全部资源后才能执行。即使有些资源最后才被该进程用到一次,但该进程在生存期间却一直占有它们,造成长期占着不用的状况。这显然是一种极大的资源浪费;

    (3)降低了进程的并发性。因为资源有限,又加上存在浪费,能分配到所需全部资源的进程个数就必然少了。    

    (4)打破循环等待条件,实行资源有序分配策略。采用这种策略,即把资源事先分类编号,按号分配,使进程在申请,占用资源时不会形成环路。所有进程对资源的请求必须严格按资源序号递增的顺序提出。进程占用了小号资源,才能申请大号资源,就不会产生环路,从而预防了死锁。这种策略与前面的策略相比,资源的利用率和系统吞吐量都有很大提高,但是也存在以下缺点:

    (1)限制了进程对资源的请求,同时给系统中所有资源合理编号也是件困难事,并增加了系统开销;

    (2)为了遵循按编号申请的次序,暂不使用的资源也需要提前申请,从而增加了进程对资源的占用时间。

    2.线程同步有几种实现方法,都是什么?

    临界区、互斥区、事件、信号量四种方式
      临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别 
      1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。 
      2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享 
      3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目 
      4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作

    3.C++以及OC单例

    #include <iostream>
    #include <memory>
    using namespace std;
    //最简单的
    class Singleton
    {
    
    public:
        static Singleton *Instance()
        {
            if (0==_instance) {
                _instance=new Singleton;
            }
            return _instance;
        }
        
    protected:
        Singleton(void)
        {
            
        }
        virtual ~Singleton(void)
        {
            
        }
        static Singleton * _instance;
        
    };
    
    //释放内存
    
    class Singleton1 {
        
        
    public:
        static Singleton1 *Instance1()
        {
            if (0==_instance1.get()) {
                _instance1.reset(new Singleton1);
            }
            return _instance1.get();
        }
        
    protected:
        Singleton1(void)
        {
            cout<<"Creat Singleton"<<endl;
        }
        virtual ~Singleton1(void)
        {
            cout<<"Destory Singleton"<<endl;
        }
        friend class auto_ptr<Singleton1>;
        static auto_ptr<Singleton1>_instance1;
    };
    
    #import "File.h"
    
    @implementation File
    
    //定义一个静态实例,并初始化为nill
    static File *sharefile=nil;
    
    +(File*)shareFile
    {
        @synchronized(self)//线程保护
        {
            //如果实例为nil,则创建该实例
            if (sharefile==nil) {
                sharefile=[[self alloc]init];
            }
        }
        return sharefile;
    }
    
    +(id)allocWithZone:(NSZone *)zone
    {
        NSLog(@"nil %p");
        @synchronized(self){
            if (sharefile==nil) {
                sharefile=[super allocWithZone:zone];
                return sharefile;
            }
        }
        return sharefile;
    }
    
    //覆盖allocWirhZone方法
    -(id)copyWithZone:(NSZone*)zone
    {
        return self;//实现copy协议,返回本身
    }
    
    -(id)retain
    {
        return self;//返回本身
    }
    
    -(NSInteger)retainCount
    {
        return UINT_MAX;//返回无符号整形范围最大值
    }
    -(oneway void)release
    {
        //什么都不做
    }
    -(id)autorelease
    {
        return self;//返回本身
    }
    @end
    

      

    4.游乐场有3条游客入场通道,但是最多只能容纳150人。请使用多线程的方式实现这个场景!

    //.h
    #import <Foundation/Foundation.h>
    
    @interface SwimAdminAppDelegate : NSObject
    {
        int count;
        int rest;
        NSThread *thread1;
        NSThread *thread2;
        NSThread *thread3;
        NSCondition *condation;
    }
    
    @property int count;
    @property int rest;
    
    -(void)fun1;
    -(void)swim;
    @end
    
    
    //.m
    #import "SwimAdminAppDelegate.h"
    
    @implementation SwimAdminAppDelegate
    @synthesize count;
    @synthesize rest;
    
    -(void)fun1
    {
        count=0;
        rest=150;
        
        condation=[[NSCondition alloc]init];
        thread1=[[NSThread alloc]initWithTarget:self selector:@selector(swim) object:nil];
        [thread1 setName:@"thread1"];
        [thread1 start];
        thread2=[[NSThread alloc]initWithTarget:self selector:@selector(swim) object:nil];
        [thread2 setName:@"thread2"];
        [thread2 start];
        thread3=[[NSThread alloc]initWithTarget:self selector:@selector(swim) object:nil];
        [thread3 setName:@"thread3"];
        [thread3 start];
        
    }
    -(void)swim
    {
        while (TRUE) {
            [condation lock];
            if(rest>0)
            {
                NSLog(@"现在还有余票:%d张,售出:%d张 线程:%@ ",rest,count,[[NSThread currentThread]name]);
                rest--;
                count=150-rest;
            }
          else
          {
              break;
          }
            [condation unlock];
        }
    }
    @end
    
    //main()
    #import <Foundation/Foundation.h>
    #import "SwimAdminAppDelegate.h"
    
    int main(int argc, const char * argv[])
    {
    
        @autoreleasepool {
            
            NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
            SwimAdminAppDelegate *swimer=[[SwimAdminAppDelegate alloc]init];
            [swimer fun1];
            [NSThread sleepForTimeInterval:10];
            
        }
        return 0;
    }
    

      

    5.写出一个异常程序,并捕获它。

    //Cup.h
    #import <Foundation/Foundation.h>
    #import "CupOverFlowException.h"
    #import "CupWarningException.h"
    
    @interface Cup : NSObject
    {
        int level; //成员变量,水的深度值
    }
    //获取水的深度值
    -(int)level;
    
    //设置水的深度值
    -(void)setLevel:(int)i;
    
    //水的深度值加10
    -(void)fill;
    
    //水的深度值减10
    -(void)empty;
    
    //输出水的深度值
    -(void)print;
    
    //计算一个百分比
    -(double)set:(double)a over :(double)b;
    
    @end
    
    //Cup.m
    #import "Cup.h"
    
    
    @implementation Cup
    
    -(id)init
    {
        if (self=[super init]) {
            [self setLevel:0];
        }
        return self;
    }
    
    -(int)level
    {
        return level;
    }
    
    -(void)setLevel:(int)i
    {
        level=i;
        if (level>100) {
            NSException *e=[CupOverFlowException exceptionWithName:@"CupOverFlowException" reason:@"the level is above 100" userInfo:nil];
            @throw e;
        }
        else if (level>=50)
        {
            NSException *e=[CupWarningException exceptionWithName:@"CupWarningException" reason:@"the level is above or at 50" userInfo:nil];
            @throw e ;//抛出异常警告
        }
        else if(level<0)
        {
            NSException *e=[NSException exceptionWithName:@"CupUnderflowException" reason:@"the level is below 0" userInfo:nil];
            @throw e;
        }
    }
    
    -(void)fill
    {
        [self setLevel:level+10];
    }
    -(void)empty
    {
        [self setLevel:level-10];
    
    }
    
    -(void)print
    {
        NSLog(@"the level is %d",level);
    }
    
    -(double)set:(double)a over:(double)b
    {
        return a/b;
    }
    @end
    
    
    
    //CupWarningException.h
    #import <Foundation/Foundation.h>
    
    @interface CupWarningException : NSException
    
    @end
    //CupWarningException.m
    #import "CupWarningException.h"
    
    @implementation CupWarningException
    
    @end
    
    
    // CupOverFlowException.h
    #import <Foundation/Foundation.h>
    
    @interface CupOverFlowException : NSException
    
    @end
    // CupOverFlowException.m
    #import "CupOverFlowException.h"
    
    @implementation CupOverFlowException
    
    @end
    
    
    //main
    #import <Foundation/Foundation.h>
    #import <Foundation/NSString.h>
    #import <Foundation/NSException.h>
    #import <Foundation/NSAutoreleasePool.h>
    #import "Cup.h"
    #import "CupWarningException.h"
    #import "CupOverFlowException.h"
    
    
    int main(int argc, const char * argv[])
    {
    
        @autoreleasepool {
            NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
        
            Cup *cup=[[Cup alloc]init];
            int i=0;
            for (i=0; i<4; i++) {
                [cup fill];
                [cup print];
            }
            
            for (i=0; i<7; i++) {
                @try {
                    [cup fill];
                }
                @catch (CupWarningException *e) {
                    NSLog(@"%@ %@",[e name],[e reason]);
                }
                @catch (CupOverFlowException *e) {
                    NSLog(@"%@ %@",[e name],[e reason]);
                }
                @finally {
                    [cup print];
                }
            }
    
            @try {
                [cup setLevel:-1];
            }
            @catch (NSException *e) {
                NSLog(@"%@ %@",[e name],[e reason]);
            }
        
            
        }
        return 0;
    }
    

      

     

     

  • 相关阅读:
    C#listbox使用方法
    poj 3894 System Engineer (二分图最大匹配--匈牙利算法)
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 连接字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 比较字符串
    Java实现 蓝桥杯VIP 算法训练 黑白无常
  • 原文地址:https://www.cnblogs.com/ymonke/p/3227513.html
Copyright © 2011-2022 走看看