久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

WinCE線程同步

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2012年07月31日   【字體:

1、線程概述
     WinCE是有優(yōu)先級的多任務操作系統(tǒng),它允許重功能、進程在相同時間的系統(tǒng)中運行,WinCE支持最大的32位同步進程。一個進程包括一個或多個線程,每個線程代表進程的一個獨立部分,而一個線程被指定為進程的基本線程。

     WinCE以搶先方式來調度線程。線程以“時間片”為單位來運行,WinCE的“時間片”通常為25毫秒。過來那個時間后,如果線程沒有放棄它的時間片,并且線程并不緊急,系統(tǒng)就會掛起線程并調度另一個線程來運行。WinCE將根據(jù)優(yōu)先級方法來決定要運行的線程,高優(yōu)先級的線程將在低優(yōu)先級的線程前面調度。

2、線程API函數(shù)
2.1 創(chuàng)建線程

     WinCE提供了CreateThread函數(shù)來創(chuàng)建線程,其聲明如下:

     HANDLE CreateThread(
          LPSECURITY_ATTRIBUTES lpThreadAttributes,     //線程安全指針,不支持
          DWORD dwStackSize,        //為自己所使用堆棧分配的地址空間大小,不支持
          LPTHREAD_START_ROUTINE lpStartAddress, //線程函數(shù)地址
          LPVOID lpParameter, //傳入線程函數(shù)的參數(shù)
          DWORD dwCreationFlags, //控制線程創(chuàng)建的附加標志
          LPDWORD lpThreadId//新線程的ID值
          );

     WinCE不支持lpThreadAttributes和dwStackSize參數(shù),將它們設置成NULL和0即可。lpStartAddress指向線程函數(shù)的地址;lpParameter被傳遞到線程中的參數(shù);dwCreationFlags線程創(chuàng)建參數(shù),可以設置成0或CREATE_SUSPENDED,如果為0,表示線程立即執(zhí)行,如果參數(shù)為CREATE_SUSPENDED,則被創(chuàng)建的線程將處于掛起狀態(tài),而且必須要調用ResumeThread函數(shù)將其喚醒。

 

2.2掛起和恢復線程

     正在運行的線程可以被掛起、暫停執(zhí)行。同他使用SuspendThead函數(shù)即可實現(xiàn)以上功能,該函數(shù)的聲明如下:

     DWORD SuspendThread( HANDLE hThread );

     參數(shù)hThead代表要掛起線程的句柄。由于SuspendThread函數(shù)的調用將增加掛起計數(shù),因此在實際調度線程運行之前,對SuspendThread函數(shù)的多次調用必須與對ResumeThread函數(shù)的多次調用相匹配。ResumeThread函數(shù)的定義

     DWORD ResumeThread( HANDLE hThread );

     參數(shù)hThead同樣代表要恢復線程的句柄。

3、線程同步

     在使用線程時,會經常遇到兩個概念,即線程沖突和線程死鎖。

     線程沖突:如果線程A讀寫數(shù)據(jù)G,線程B也正在讀取數(shù)據(jù)G,那么很顯然,該操作將導致數(shù)據(jù)沖突,引起數(shù)據(jù)混亂。這里需要使用同步技術,以保證線程A和線程B依次讀寫數(shù)據(jù)G,避免數(shù)據(jù)沖突。

     線程死鎖:例如A工人為加工III零件在等待B提供的I零件,而B正好在等待應由A加工提供的II零件來裝配I零件。由于他們之間再沒有其他的任何人幫助通信或其他通信手段。所以他們一直在等對方的零件而進入死鎖狀態(tài)。死鎖屬于邏輯錯誤,無法通過線程同步來解決。

     WinCE實現(xiàn)線程同步的常用方法:事件(Event)、互斥(Mutex)、信號量(Semaphore)、臨界區(qū)(CriticalSection)。

3.1 利用事件同步

     “事件對象”是實現(xiàn)線程同步最基本的方法之一,一個事件對象可以處于“已標示”和“未標示”兩種狀態(tài),如果將事件對象設置為“已標示”狀態(tài),表示可以執(zhí)行同步操作,事件對象處于“未標示”狀態(tài),則表示需要等待事件對象變?yōu)?ldquo;已標示”狀態(tài)才可以進行同步操作。下面介紹利用事件同步所需要的API函數(shù)。

(1)CreateEvent函數(shù)。創(chuàng)建事件對象函數(shù)CreateEvent,其聲明如下:

      HANDLE CreateEvent(
          LPSECURITY_ATTRIBUTES lpEventAttributes,//CE不支持,設為NULL
          BOOL bManualReset, //設置是否手動設置事件對象狀態(tài)
          BOOL bInitialState, //事件對象初始狀態(tài)
          LPTSTR lpName //事件對象名稱
          );

     參數(shù)bManualReset表示是否手動設置事件對象狀態(tài),當其值為TRUE時,在調用完等待函數(shù)(WaitForSingObject,WaitForMutipleObject)后,則必須調用ResetEvent函數(shù),以設置事件對象沒有被標示,當其值為FALSE時,系統(tǒng)調用完等待函數(shù),會自動將事件對象設置為未標示狀態(tài)。

     參數(shù)bInitialState表示事件對象初始狀態(tài),當其值為TRUE是,事件對象初始化狀態(tài)為已標示,當其值為FALSE時,事件對象初始狀態(tài)為未標示。

     如果創(chuàng)建事件函數(shù)對象CreateEvent執(zhí)行成功,將返回事件對象句柄。若失敗,則返回0,在不用事件句柄時,需要使用CloseHandle()將其關閉,以釋放資源。

(2)SetEvent函數(shù)和ResetEvent函數(shù)。函數(shù)SetEvent()的功能是將事件對象設置為已標示狀態(tài)。該函數(shù)的聲明如下:

     BOOL SetEvent(HANDLE hEvent);

     參數(shù)hEvent表示事件對象句柄。

     函數(shù)ResetEvent函數(shù)功能將事件對象設置成未標示狀態(tài),該函數(shù)的聲明如下:

     BOOL ResetEvent(HANDLE hEvent);

(3) 使用事件同步的一般使用流程

     通常情況,在主線程中,用戶利用CreateEvent函數(shù)創(chuàng)建一個事件對象,并且將參數(shù)bManualReset設為FALSE,參數(shù)bInitialState也設為FALSE,此時事件對象狀態(tài)未標示。然后在線程里通過WaitForSingleObject函數(shù)來等待事件被標示。此時,只要在主線程中調用SetEvent函數(shù),將事件對象設置成已標示。那么線程里的WaitForSingleObject函數(shù)便會返回,繼續(xù)執(zhí)行,同時將事件對象狀態(tài)設置成未標示。

3.2 利用互斥同步

     互斥同步類似于事件對象同步。互斥同步也將創(chuàng)建一個互斥對象,該互斥對象也有“被線程擁有”和“不被線程擁有”兩種狀態(tài);當互斥對象處于“不被線程擁有”狀態(tài),表示可以執(zhí)行相關操作;當互斥對象處于“被線程擁有”狀態(tài),表示此時不可以執(zhí)行相關操作。通過等待函數(shù)請求互斥對象實現(xiàn)同步。

(1)CreateMutex函數(shù)。通過CreateMutex函數(shù)創(chuàng)建互斥對象,該函數(shù)定義如下:

     HANDLE CreateMutex(
          LPSECURITY_ATTRIBUTES lpMutexAttributes, //CE不支持
          BOOL bInitialOwner, //初始化擁有狀態(tài),TRUE表示擁有,F(xiàn)ALSE表示未被擁有
          LPCTSTR lpName //互斥名稱
          );

     如果創(chuàng)建互斥函數(shù)對象CreateMutex執(zhí)行成功,將返回互斥對象句柄。若失敗,則返回ERROR_INVALID_HANDLE,在不用互斥句柄時,需要使用CloseHandle()將其關閉,以釋放資源。

(2)ReleaseMutex函數(shù)。在使用等待函數(shù)請求互斥對象時,如果請求到互斥對象的擁有權,則等待函數(shù)將自動設置互斥對象狀態(tài)為“未被擁有”。ReleaseMutex函數(shù)負責釋放某個線程對象互斥對象的擁有權,也就是將互斥對象設置為“未被線程擁有”狀態(tài)。ReleaseMutex函數(shù)定義如下:

     BOOL ReleaseMutex( HANDLE hHandle);hHandle表示互斥對象句柄;

(3)利用互斥同步的一般使用流程

     利用互斥同步的一般使用流程是:首先利用CreateMutex函數(shù)創(chuàng)建互斥對象,并將CreateMutex中的參數(shù)bInitialOwer設置為FALSE,使互斥對象處于“未被線程擁有”狀態(tài)。然后利用WaitForObject等待互斥對象,執(zhí)行相關操作。處理完成后,利用ReleaseMutex函數(shù)釋放線程對互斥對象的擁有權。當所有線程執(zhí)行完畢后,需要使用CloseHandle()將其關閉。

3.3 利用臨界區(qū)同步

     “臨界區(qū)”是進行線程同步的另一種方法,它能夠阻止兩個或多個不同的線程在同一時間內訪問同一個代碼區(qū)域。它通過調用 EnterCriticalSection函數(shù)來指出已經進入代碼的臨界區(qū),如果另一線程也調用了EnterCritialSection函數(shù),并且參數(shù)指向同一臨界區(qū)對象,那么另一線程將阻塞,直到第一個線程調用了LeaveCriticalSection函數(shù)離開臨界區(qū)為止。

臨界區(qū)同步所需要的API函數(shù):

(1) InitializeCriticalSection函數(shù)。如果要使用臨界區(qū),首先要使用InitializeCriticalSection函數(shù)創(chuàng)建臨界區(qū),該函數(shù)定義如下:

     void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection );

(2) DeleteCriticalSection 函數(shù),當結束使用臨界區(qū)對象時,必須調用DeleteCriticalSection 函數(shù)釋放臨界區(qū)對象所占有的資源。該函數(shù)定義如下:

     void DeleteCriticalSection(   LPCRITICAL_SECTION lpCriticalSection );

(3)EnterCriticalSection函數(shù),在創(chuàng)建了臨界區(qū)對象后,需要調用EnterCriticalSection函數(shù)進入臨界區(qū),以保護代碼,該函數(shù)定義如下:

     void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

如果臨界區(qū)對象已經屬于另一個線程,那么此函數(shù)將阻塞直到另一線程離開臨界區(qū)才返回。

(4)LeaveCriticalSection函數(shù)。如果要離開臨界區(qū),只需要調用LeaveCriticalSection函數(shù)即可。該函數(shù)定義如下:

     void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);

3.4 利用信號量同步

     信號量是建立在互斥基礎上,并增加了資源計數(shù)的功能。它允許預定數(shù)目的線程同時進入要同步的代碼。通過設置信號量計數(shù)為1,只允許一個線程同時訪問同步代碼,而實現(xiàn)線程同步。信號量同步所需要的API函數(shù):

(1) CreateSemaphore函數(shù)。在使用信號量實現(xiàn)同步時,需要調用CreateSemaphore函數(shù)創(chuàng)建信號量對象。該函數(shù)定義如下:

     HANDLE CreateSemaphore(
          LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //CE不支持
          LONG lInitialCount, //信號量初始化計數(shù)值
          LONG lMaximumCount, //信號量計數(shù)最大值
          LPCTSTR lpName //信號量對象名稱
          );

     如創(chuàng)建信號量成功,函數(shù)返回信號量對象句柄,否則返回NULL值。

(2)ReleaseSemaphore函數(shù)。在使用等待函數(shù)請求信號量時,等待函數(shù)自動給信號量計數(shù)減1,那么當計數(shù)減到0時,信號量對象將不能被請求。ReleaseSemaphore函數(shù)負責給信號量計數(shù)加值,使信號量可以被請求。此函數(shù)定義如下:

     BOOL ReleaseSemaphore(
          HANDLE hSemaphore, //信號量句柄
          LONG lReleaseCount, //信號量計數(shù)增加的值
          LPLONG lpPreviousCount //輸出量,表示上一次信號量計數(shù)
          );

3.5 利用互鎖函數(shù)可對變量和指針進行原子的讀/寫操作。因為它們不需要額外的同步對象,所以有時這些互鎖函數(shù)特別有用。Windows ce提供的互鎖函數(shù)有:

     InterlockedIncrement             //把一個變量的值加1
     InterlockedDecrement
     InterlockedExchange             //交換兩個變量的值
     InterlockedTestExchange          //根據(jù)條件交換變量的值
     InterlockedCompareExchange       //根據(jù)比較原子交換
     InterlockedCompareExchangePointer //根據(jù)比較原子交換指針
     InterlockedExchangePointer        //交換兩個指針的值
     InterlockedExchangeAdd           //給某個變量嗇某個特定值
關閉窗口

相關文章

主站蜘蛛池模板: 成人免费精品 | 日韩aⅴ视频 | 久久一区二区免费视频 | 国产高清视频一区 | 日韩免费一二三区 | 日韩美香港a一级毛片免费 国产综合av | 欧美日韩国产传媒 | 国产丝袜av| 午夜爱爱毛片xxxx视频免费看 | 国产精品久久久久久久久久 | 亚洲欧洲精品在线 | www国产精品 | 国产高清在线精品一区二区三区 | 国产成人久久精品一区二区三区 | 欧美精品在线视频 | 天天干天天爱天天 | 在线观看日本网站 | 午夜在线 | 国产片网站 | 亚洲一区二区在线视频 | 久久一区二区三区四区五区 | 日韩一二区在线 | 欧美一区在线看 | 久草在线青青草 | re久久| 午夜精品一区 | 殴美黄色录像 | 亚洲成人免费视频在线 | a级大片免费观看 | 91精品久久久久久久久 | 久久毛片| 偷拍自拍网 | 69av在线视频| 日本久久一区 | 久久久精品影院 | 国产精品一区一区三区 | 国产精品久久国产精品 | 一本一道久久a久久精品蜜桃 | 91久久精品一区二区三区 | 日韩精品一二三 | 91精品国产色综合久久不卡98 |