关于解决假死锁的设想

来源:互联网 发布:电脑远程软件安卓版下 编辑:程序博客网 时间:2024/05/17 12:07

      在我的上一篇文章《关于多线程(进程)死锁的探测》中已经论述过死锁形成的条件,其中主是讲了真死锁,也就是待锁定环死锁的形成及解决方式。但是,有一种类型的死锁没有涉及到,那就是以待锁定链形式出现的死锁。

      待锁定链要形成死锁有一个必要的条件就是,从Y集合的<Oa,Ra>偶对出发所画出的待锁定链图形中,必然有至少一个点<On,Rn>具有以下的特点——On长时间占有Rn资源而不释放。

     从On占有Rn的那一个时间点T1开始,到On释放Rn的那一个时间点T2结束。这段时间内<Oa,Ra>到<On,Rn>路径中的所有节点(含有<Oa,Ra>,但不含有<On,Rn>),都必然被阻塞,无法运行下去。这时,我们可以认为在时间段T1T2内On在Rn上形成了对其它线程或进程的死锁。如果要解决这个问题,怎么办?唯一的办法,就是不允许任何一个进程或线程长时间占用共享的资源对象。也就是说,每个进程或线程在申请一个资源时,必须指明它占用这个资源的时间,一旦超出了这个时间范围,就要向这个进程或线程抛出异常。这个东西只有靠具有新的语法的编程语言来解决,到现有为止,还没找到那程语言可以无缝的实现这一特性。

     

      可以设想具有这样特性的语言的语法类似如下的结构:

      lock(object,1000)

     {

        执行语句 ......

        ......

     }

     timeout

     {

        处理超时的代码......

        ......

     }

     后续的业务代码......

     ......

 

      这个结构有点类似于Java的多线程同步语法,只不过把关键字换了一下而亦。当要锁定对象object时,除了指明这个对象外,还需要指明它被锁定的时间。如果程序在规定的时间内执行完了lock体中的代码,那么就应该自然跳到后续的业务代码里。如果程序没能在规定的时间内执行完lock体中的代码,好么程序就要跳到timeout体中执行超时处理代码。当程序跳到timeout中时,应该自动释放object对象。同样执行完timeout中的内容,程序也会顺序执行下面的业务代码。

      这个lock、timeout结构,实际上是模拟的try、catch结构。如何实现它呢?这点就要编程语言去实现它了。可以设想的一种实现方案是:

      可以设置一个锁定的栈,当有锁定了某个对象时,将这个对象及锁定的时间(包括什么时间点锁定的,要锁定多长的时间段)、异常处理代码段指针组合成一个组合对象压入这个栈。正常退出时将锁定对象从栈中弹出。在将对象压入时,有一个要求——要检查栈顶的对象的锁定时间段。如果栈顶对象的锁定时间段小于当前对象,就要将当前对象的锁定时间段更改为栈顶对象的时间段。

      如果是异常退出,先跳出栈顶对象,再跳到相应的timeout体中执行。执行完了timeout体,还需要根据当前的时间点计算出现有的栈顶对象是否也超时了。如果超时,重复上述的操作。要检查出这些超时,可行的一种设想就是——每隔一段代码,插入一个时间检查点,检查当前栈顶对象的锁定是否超时。这些检查点应该是由程序编译器依据一定的规则自动插入的,对程序员应该是透明的。

 

 

 

 

 

 

严家俊                 

2010年1月27日 夜 于家中

原创粉丝点击