IT Course

Technology Collection: Ruijin.R.Zhao

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::
一,临界区:
     一个线程访问共享的,可修改的时,我们就说它进入了一个临界区(critical section 或 criticl region).

二,互斥问题
1,第一个版本的互斥Dekker算法(Lookstep同步和Busy Waiting)
int threadNumber = 1;
startThreads();
线程T1:
void main()

      while (!done) 
      { 
            while (threadNumber == 2) ;   //线程反复测试threadNumber值,我就说它处于Busy waiting,暂用处理器时间来做无用工作
            //critical section code threadNumber = 2;
       }

 线程T2:
void main()

      while (!done) 
      { 
            while (threadNumber == 2) ; 
            //critical section code threadNumber = 2;
       }
}
1),同时启动这2个线程,除非变量threadNumber等于线程号,否则将while循环下去,效率低下。
2),违反互斥原则,不在临界区的线程不应该影响其他希望进入临界区的线程。而这里必须等到T1进入设置threadNumber=2后,T2才可进入。

2, 第2个版本互斥
     t1Inside = t2Inside = false;
       线程T1:
        void main()
        {
            while (!done)
            {
                while (t2Inside) ;           (1) t2Inside = false
                t1Inside = true;            (2)此处在执行前,被T2抢占时

                //critical section code      (4)进入临界区 1

                t1Inside = false;
            }
      线程T2:
        void main()
        {
            while (!done)
            {
                while (t1Inside) ;          (3)t1Inside = false;
                t2Inside = true;           (4)进入临界区 2

                //critical section code

                t1Inside = false;f
            }
        }
2个线程同时都进入了临界区,违反互斥原则。

3,第三个版本(死锁)

      线程T1: 
       void main()
        {
            while (!done)
            {
                t1WantsToEnter = true;

                while (t2WantsToEnter) ;    //T2想进入临界区,则t1等待

                //critical section code

                t1WantsToEnter = false;
            }
        }
      线程T2:
      void main()
        {
            while (!done)
            {
                t2WantsToEnter = true;

                while (t1WantsToEnter) ;       //T1想进入临界区,则t2等待

                //critical section code

                t2WantsToEnter = false;
            }
        }

     假设每个线程同时都发现另一个线程标志为true(即都想进入),那么while就会永远下去,形成死锁。

4,第四个版本(引入无限延期问题)

      线程T1: 
       void main()
        {
            while (!done)
            {
                t1WantsToEnter = true;

                while (t2WantsToEnter)  
               {
                      t1WantsToEnter  = false;
                      //waiting for small, randow amount of time
                     t1WantsToEnter  = true;
               }

                //critical section code

                t1WantsToEnter = false;
            }
        }
      线程T2:
      void main()
        {
            while (!done)
            {
                t2WantsToEnter = true;

                while (t1WantsToEnter) 
               {
                      t2WantsToEnter  = false;
                      //waiting for small, randow amount of time
                     t2WantsToEnter  = true;
               }

                //critical section code

                t2WantsToEnter = false;
            }
        }

     我们不能预测异步发生并发的速度,因此与形成死锁类似,也是可能形成无限延期问题,虽然可能性很低,但对于需要严格用途的地方造成伤害。

5,第五个版本Dekker算法(正确方案)

      线程T1: 
       void main()
        {
            while (!done)
            {
                t1WantsToEnter = true;

                while (t2WantsToEnter)   //(1)当T2想进入且T1是优先线程,则T1跳过if判断,等待T2将t2WantsToEnter设置为false。
               {                                   //(1)当T2想进入且T2是优先线程,则T1进入if判断
                      if(favoredThread == 2)
                      {
                              t1WantsToEnter  = false;
                              while(favoredThread == 2);    //(2)测试T2是否任然保持是优先线程
                              t1WantsToEnter  = true;      //(3)当T2执行完毕退出时,将t2WantsToEnter=false,favoredThread =1,则T1回到(1)开始进入自己
                                                                              临界区。如果T2退出时,又抢占将自己设置为true,可优先线程已经是1,将等到T1执行。
                      }
                 }

                //critical section code

                favoredThread = 2;

                t1WantsToEnter = false;
            }
        }
      线程T2:
      void main()
        {
            while (!done)
            {
                t2WantsToEnter = true;

                while (t1WantsToEnter)  
               {
                      if(favoredThread == 1)
                      {
                              t2WantsToEnter  = false;
                              while(favoredThread == 1);
                              t2WantsToEnter  = true;
                      }
                 }

                //critical section code

                favoredThread = 1;

                t2WantsToEnter = false;
            }
        }

   

6, Perterson 算法

      线程T1: 
       void main()
        {
            while (!done)
            {
                t1WantsToEnter = true;
                favoredThread = 2;

                while (t2WantsToEnter && favoredThread == 2)  ;              
                //critical section code

                t1WantsToEnter = false;
            }
        }
      线程T2:
       void main()
        {
            while (!done)
            {
                t2WantsToEnter = true;
                favoredThread = 1;

                while (t1WantsToEnter && favoredThread == 1)  ;              
                //critical section code

                t2WantsToEnter = false;
            }
        }

   

7, N线程互斥算法

      boolean choosing[n]   //记录哪些线程是否取票
      int ticketp[n]; //票据
      线程Tx
      void main()
      {
            x = ThreadNumber(); //保存当前线程号;
            while(!done)
            {
                  chooseing[x] = true; //开始取票
                  ticket[x] = maxValue(ticket) + 1;
                  chooseing[x] = false; //取票完毕
                  for(int i = 0; i < n; i++)  //根据比较票据,来叫号
                  {
                        if(i == x) //如果是当前自己,就不需要检查
                        {
                              continue;
                        }
                        while( chooseing[i] != false ); //在进入临界区之前,其他线程如果没有选好号,则等待。
                        while( ticket[i] != 0 && ticket[i] < ticket[x] ); //如果当前线程的票号不是最小的,则等待
                        if(ticket[i] == ticket[x] && i < x)
                        {
                              while( ticket[i] != 0); //等待离开临界区
                        }
                  }
                  //critical section code
                  ticket[x] = 0;
            }
      }

posted on 2009-07-28 22:15  tommy007  阅读(434)  评论(0)    收藏  举报