新聞中心

        EEPW首頁 > 學習方法與實踐 > 線程結構學習筆記

        線程結構學習筆記

        ——
        作者: 時間:2007-03-06 來源: 收藏

         

        Cyg_Thread分析
        依然是從數據結構開始:
         enum {            // Thread state values
            
            RUNNING  = 0,     // Thread is runnable or running,正在運行,或者條件就緒,等待CPU
            SLEEPING  = 1,     // Thread is waiting for something to happen,休眠態,等待著事件發生(不報含等待CPU),
            COUNTSLEEP = 2,     // Sleep in counted manner,休眠態,等待記數器到達指定的數值
            SUSPENDED = 4,     // Suspend count is non-zero,掛起,且計數器非零
            CREATING  = 8,     // Thread is being created,線程正在被創建,代碼中未發現使用該狀態
            EXITED   = 16,     // Thread has exited,線程已經退出

            // This is the set of bits that must be cleared by a generic
            // wake() or release().
            SLEEPSET  = (SLEEPING | COUNTSLEEP)  //休眠集合,通常由wake()函數或者release()函數清除。
          };

         

         cyg_uint32         state;       //記錄線程的狀態

          // Suspension counter, if > 0, the thread is suspended,掛起計數器,大于0表示線程處于掛起的狀態
          cyg_ucount32        suspend_count;

          // Wakeup counter, if > 0, sleep will not sleep, just decrement,喚醒計數器,大于0時,線程將不會休眠,僅僅是此數值減1
          cyg_ucount32        wakeup_count;

          // A word of data used in syncronization object to communicate
          // information between sleepers and wakers.
          CYG_ADDRWORD        wait_info;    //等待信息,說明線程等待的事件,用于休眠線程和喚醒線程之間的通信
          
          // Unique thread id assigned on creation,線程ID,每個線程都有一個唯一的ID
          cyg_uint16         unique_id;

        Cyg_Exception_Control    exception_control;//異??刂凭浔?/P>

         enum cyg_reason           // sleep/wakeup reason codes 休眠/喚醒的原因
          {
            NONE,              // No recorded reason,未記錄的原因
            WAIT,              // Wait with no timeout,正在等待定時器時刻到來
            DELAY,             // Simple time delay,簡單的事件延遲
            TIMEOUT,            // Wait with timeout/timeout expired,等待時間到
            BREAK,             // forced break out of sleep,強行脫離休眠狀態
            DESTRUCT,            // wait object destroyed[note],等待對象給destory
            EXIT,              // forced termination,線程被強行終止
            DONE              // Wait/delay complete,等待/延遲結束
          };

        #ifdef CYGFUN_KERNEL_THREADS_TIMER
          Cyg_ThreadTimer   timer;     // per-thread timer,線程定時器,每個線程都會有一個
        #endif

          cyg_reason     sleep_reason;  // reason for sleeping,休眠原因

          cyg_reason     wake_reason;  // reason for waking,喚醒原因
         char            *name;      //線程名稱
          Cyg_Thread         *list_next;    //指向下一個線程的指針
          static Cyg_Thread      *thread_list;    //指向線程鏈表的指針

        下面詳細分析線程狀態的切換,以及切換原因的分析

         cyg_uint32         state;       //記錄線程的狀態

        (1)線程剛剛創建的時候線程狀態為SUSPENDED,參見Cyg_Thread類的構造函數。

          // Start the thread in suspended state.
          state        = SUSPENDED;
          suspend_count    = 1;
          wakeup_count    = 0;

          // Initialize sleep_reason which is used by kill, release
          sleep_reason    = NONE;
          wake_reason     = NONE;

        (2)sleep() 函數:將RUNNING轉換為SLEEPING,注意直接與SLEEPING相或,因為RUNNING的值為0
         // If running, remove from run qs
          if ( current->state == RUNNING )
            Cyg_Scheduler::scheduler.rem_thread(current);

          // Set the state
          current->state |= SLEEPING;

        (3)wake()函數:清除SLEEPSET,此時可能還有別的狀態,因此要進一步判斷是否為RUNNING

        if( 0 != (state & SLEEPSET) )
          {
            // Set the state
            state &= ~SLEEPSET;

            // remove from any queue we were on
            remove();

            // If the thread is now runnable, return it to run queue
            if( state == RUNNING )
              Cyg_Scheduler::scheduler.add_thread(this);

          }
        (4)counted_sleep()函數(后一個為定時器版本):wakeup_count為0,進入休眠態,否則wakeup_count--
         if ( 0 == current->wakeup_count ) {
            set_sleep_reason( Cyg_Thread::WAIT );
            current->sleep();        // prepare to sleep
            current->state |= COUNTSLEEP;  // Set the state
          }
          else
            // there is a queued wakeup, do not sleep
            current->wakeup_count--;

        if ( 0 == current->wakeup_count ) {

            // Set the timer (once outside any waiting loop.)
            set_timer( Cyg_Clock::real_time_clock->current_value()+delay,
                     Cyg_Thread::TIMEOUT );

            // If the timeout is in the past, the wake reason will have been
            // set to something other than NONE already.
          
            if( current->get_wake_reason() == Cyg_Thread::NONE )
            {
              set_sleep_reason( Cyg_Thread::TIMEOUT );
              current->sleep();        // prepare to sleep
              current->state |= COUNTSLEEP;  // Set the state

              Cyg_Scheduler::reschedule();
          
              // clear the timer; if it actually fired, no worries.
              clear_timer();
            }
          }
          else
            // there is a queued wakeup, do not sleep
            current->wakeup_count--;

        (5)counted_wake()函數:
        if ( 0 == (state & COUNTSLEEP) )  // already awake, or waiting:
            wakeup_count++;         // not in a counted sleep anyway.
          else {
            sleep_reason = NONE;
            wake_reason = DONE;
            wake();             // and awaken the thread
          }
        (6)suspend()函數:suspend_count計數器,每調用一次該數值增加1。如果原來在運行態,要退出運行隊列。注意后面的或運算。
          suspend_count++;
          
        #ifdef CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT
          CYG_ASSERT( CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT > suspend_count,
                "suspend_count overflow" );
        #endif

          // If running, remove from run qs
          if( state == RUNNING )
            Cyg_Scheduler::scheduler.rem_thread(this);

          // Set the state
          state |= SUSPENDED;
        (7)resume()函數:suspend_count--,如果為0,且狀態變為RUNNING進入運行隊列。
        if( suspend_count == 1 )
          {
            suspend_count = 0;

            CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
            
            // Set the state
            state &= ~SUSPENDED;

            // Return thread to scheduler if runnable
            if( state == RUNNING )
              Cyg_Scheduler::scheduler.add_thread(this);
          }
          else
            if( suspend_count > 0 )
              suspend_count--;
        (8)force_resume()函數:suspend_count置零,如果為RUNNING,則進入RUNNING隊列
        if ( 0 < suspend_count ) {
            suspend_count = 0;

            CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
            
            // Set the state
            state &= ~SUSPENDED;

            // Return thread to scheduler if runnable
            if( state == RUNNING )
              Cyg_Scheduler::scheduler.add_thread(this);
          }
        (9)exit()函數:進入EXITED狀態,并從運行隊列中刪除(確定一定在運行隊列嗎?)
        if( self->state != EXITED )
          {
            self->state = EXITED;

            Cyg_Scheduler::scheduler.rem_thread(self);
          }

        (10)kill函數:如果是運行態要先退出
         case NONE:
            // The thread is not sleeping for any reason, it must be
            // on a run queue.
            // We can safely deschedule and set its state.
            if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this);
            state = EXITED;
            break;
        (11)set_priority():線程在運行態要先退出運行隊列,如果是休眠態也要退出所在的隊列

        // If running, remove from run qs
          if( state == RUNNING )
            Cyg_Scheduler::scheduler.rem_thread(this);
          else if( state & SLEEPING )
          {
            // Remove thread from current queue.
            queue = get_current_queue();
            // if indeed we are on a queue
            if ( NULL != queue ) {
              CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");    
              remove();
            }
          }

        優先級設置完畢后,要重新放回原來的隊列。注意從原來的隊列中刪除時并沒有改變響應的狀態。
        if( state == RUNNING )
            Cyg_Scheduler::scheduler.add_thread(this);
          else if ( state & SLEEPING )
          {
            // return to current queue
            // if indeed we are on a queue
            if ( NULL != queue ) {
              CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");
              queue->enqueue(this);
            }
          }

        由上述11個函數,我們可以對線程狀態有個大概了解。

        (1)線程剛剛創建的時候線程狀態為SUSPENDED
        (2)RUNNING 通過sleep函數變為SLEEPING態
        (3)wake函數清除SLEEPSET狀態
        (4)counted_sleep()函數在wakeup_count==0進入COUNTEDSLEEP狀態,否則wakeup_count--
        (5)counted_wake()函數清除COUNTSLEEP狀態,如果已經清除則wakeup_count開始計數
        (6)suspend函數進入SUSPEND狀態,并增加suspend_count計數器
        (7)resume()suspend_count計數器--,為0消除SUSPENDED狀態
        (8)force_resume()直接清除SUSPENDED狀態
        (9)exit函數進入EXIT狀態
        (10)kill函數進入EXIT狀態

        suspend_count計數器的操作:suspend函數加1,resume函數減1
        wake_count計數器的操作:
          cancel_counted_wake()清0;
          counted_sleep()函數在wakeup_count==0進入COUNTEDSLEEP狀態,否則wakeup_count--;
          counted_wake()函數在COUNTSLEEP狀態清除后每調用一次,wakeup_count++

        塵埃粒子計數器相關文章:塵埃粒子計數器原理


        關鍵詞: 線程結構

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 安国市| 和静县| 舒城县| 沐川县| 靖江市| 桃园县| 监利县| 宁蒗| 确山县| 宿迁市| 昌乐县| 罗甸县| 洱源县| 沙河市| 西藏| 双江| 平罗县| 祥云县| 美姑县| 达州市| 通城县| 浏阳市| 阿巴嘎旗| 女性| 左贡县| 古田县| 稷山县| 油尖旺区| 南京市| 县级市| 南汇区| 云龙县| 南康市| 永胜县| 元朗区| 瓦房店市| 昭觉县| 子长县| 永年县| 呼玛县| 常州市|