?? 借助vc++實現串口通訊程序中的多線程應用.txt
字號:
借助VC++實現串口通訊程序中的多線程應用
-------------------------------------------------------------------------
1、概述
在廣電網絡數字化雙向改造中,為了實現廣電網絡對多媒體數字業務的支持,在廣電網絡主干網和支干網上建設了大量的無人值守的支持數字業務的中心機房,隨著現在數據業務的開展,業務平臺的安全以及廣播電視的安全播出的迫切需要,必須建立相應的對這些無人值守機房進行遠程實時監控和通訊的管理系統。在這些遠程實時監控和通訊的管理系統中,信息實時性是最主要的技術要求之一,所以在遠程實時監控和通訊管理系統的程序設計中滿足實時性要求是軟件設計的根本出發點之一。WINDOWS系統是搶先式的多任務操作系統,程序對CPU的占用時間由系統決定。多任務就是指操作系統可以同時運行多個進程,每個進程又可以同時執行多個線程。進程是應用程序的運行實例,要求擁有自己的地址空間,每個進程擁有一個主線程,同時可以建立其他的線程。線程是操作系統分配CPU 時間的基本實體,每個線程占用的CPU時間由系統分配,系統不停的在各個線程之間切換。進程中的線程共享進程的虛擬地址空間,可以訪問進程的資源,處于并行執行狀態,所以在串行通訊程序中應用多線程就可以簡化應用程序的結構,把一些復雜的運算放在后臺并行執行,從而大大提高應用程序的響應實時能力。
2、VC++對多線程的支持
在VC++編程中通常使用MFC程序進行開發,這樣可以減少程序代碼的書寫。在VC++6.0版本中的MFC應用程序的線程是由CwinThread對象表來表示的,該線程分為兩種:用戶界面線程(GUI-Thread)和工作者線程(Worker-Thread)。用戶界面線程能夠提供界面和用戶交互,用于處理用戶輸入和響應各種信息和事件;工作者線程主要用來處理應用程序的后臺任務。應用程序可以通過調用AfxBejinThread()函數自動創建一個CwinThread對象,從而開始一個線程。線程的終止條件有如下4種:線程函數返回;線程調用ExitThtead()退出;異常情況下用現成的句柄調用TerminateThread()退出;線程所屬的進程被終止。
3、多線程在RS-322串口通信中的應用
3.1 串口通信對線程同步的要求
因為同一進程的所有線程共享進程的虛擬地址空間,而在WINDOWS中線程是匯編級中斷,所以才有可能實現多個線程同時訪問同一個對象。這些對象可以是全局變量、MFC的對象、MFC的API等。而串口通信對每個串口對象只提供一個緩沖區,發送接收都要用到這一個緩沖區,所以要求必須建立同步線程執行,使得一個時刻只能進行一種線程操作,以免通信出錯。串口通信處理的多個線程需要協調運行,一個線程必須等待另一線程結束才能開始,在處理一個線程的同時必須把其余待處理的線程掛起等待,以減少其余待處理線程對CPU的資源占用,正處理的線程一旦處理結束則通過線程間的通信發出信號來擊活被掛起的線程中的一個線程進入處理。VC++提供了以下4個同步對象來協調實現多線程的并行:
Csemaphore信號燈對象,允許一定數量的現成訪問某個資源,用來控制訪問共享資源的線程數量。
Cmutex互斥量對象,一個時刻至多只允許一個線程訪問某個資源,未被占用時處于有信號狀態,可實現對共享線程的互斥訪問。
Cevent事件對象,用于使一個線程統治其余現成某個事件正發生,所以可以用來實現禁止對某個資源的訪問,直至該線程結束釋放資源使資源處于有信號狀態,從而使被掛起的線程被通知得以執行
CcriticalSection臨界區對象,將一段代碼置入臨界緩沖區,并只允許一個線程進入執行這段代碼,該臨界緩沖區僅在創建這個緩沖區的進程中有效。
3.2 等待函數
為了實現線程在資源對象被占用時把自己掛起而阻塞自己執行,等待資源空閑信號停止阻塞繼續執行,從而減少對CPU的資源占用,WIN32 API中提供了兩個等待函數來實現這一功能:WaitForSingleObject()(只可監控單個同步對象)WaitForMUultipleObjects(可同時監控多個同步對象)。在監控系統中,處理串口通信只是CPU的一部分事物,所以必須使用等待函數提高程序的執行效率。
3.3 串口通信的重疊I/O方式
MFC對于串口通信是作為文件設備來處理的,用CreateFile()打開串口獲得一個串口句柄。打開后由SetCommState()進行串口端口配置:緩沖區設置、超時設置、數據格式設置等等。設置成功后就可以調用ReadFile()和WriteFile()進行數據的讀與寫,用WaitCommEvent()監控通信事件。CloseHandle()用于關閉串口。在ReadFile()和WriteFile()進行串口讀寫時可以采取同步執行方式也可以采用重疊I/O方式。由于采用同步執行方式,被調用的函數必須執行結束后才被返回,這必然要求除正被執行線程外其余線程被掛起等待,效率低;而采用重疊I/O方式,被調用的函數不必等執行結束后才被返回,而是可以立即返回,因為I/O操作在后臺執行,這樣其他線程就不必等待馬上可以進行處理其他事物,實現了不同線程可以在同一串口句柄上基本上接近同時實現讀寫操作,實現重疊,是通信的實時性提高。
采用重疊I/O方式,線程必須創建OVERLAPPED結構攻讀寫函數使用,該結構最重要的成員是hEvent事件句柄。它將作為線程的同步對象使用,讀寫函數完成時hEvent處于有信號狀態,表示可以進行讀寫操作;讀寫函數未完成時hEvent被置于無信號狀態。
4、多線程應用在串口通信程序中的實現
應用程序需專門建立一個串口通信類,并在串口通信相關程序段中應用相關函數實現多線程的應用,下面給出實現多線程應用的的關鍵函數的核心代碼。
1).專門針對COM1的初始化程序段(只寫出涉及多線程應用的關鍵步驟)
BOOL InitComm()//串口初始化
{
HANDLE m_hComm;
COMMTIMEOUTS m_CommTimeouts;
m_hComm = CreateFile(“COM1” , //這里只使用串口1,如要對多個串口初始化需先在初始化前進入代碼臨界區,以保證在某時刻只對一個串口初始化
GENERIC_READ | GENRIC_WRITE, //定義串口打開類型為可讀寫
0, //以獨占串口資源模式打開串口
NULL, //對該串口不設置安全屬性
OPEN_EXISTING,FILE_FLAG_OVERLAPPED, //設置重疊I/O模式
0;)
if (m_hComm==INVALID_HANDLE_VALUE) //串口打開不成功
{return FALSE;}
m_CommTimeouts.ReadIntervalTimeout = 1000; //進行超時設置,具體量值根據實際需要調整
m_CommTimeouts.ReadTotaloutMultiplier = 500; //進行超時設置
m_CommTimeouts.ReadTotaloutConstant = 5000; //進行超時設置
m_CommTimeouts.WriteTotaloutMultiplier = 500; //進行超時設置
m_CommTimeouts.WriteTotaloutConstant = 5000; //進行超時設置
if(! SetCommTimeouts(m_hComm,&m_CommTimeouts))
{CloseHandle(m_hComm);
return FALSE;}
PurgeComm (m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT |PURGE_TXABORT); //清除串口緩沖區
Reture TRUE;
}
在上述串口初始化成功后,監控應用主程序就可以通過應用AfxBejinThread()函數來建立串口監控用的工作者線程從而實現對該串口通信多線程的并行管理,如果要對多個串口同時監控,可以分別對各個串口建立監控線程,各自實現對應串口的通信多線程的并行管理。下面是建立串口監控用的工作者線程的關鍵程序段代碼(只寫出涉及多線程應用的關鍵步驟)。
UINT CommThread(LPVOID pParam) //用于監控串口用的工作者線程
{
BOOL bResult = FLASE;
If(m_hComm) //查看前述串口初始化程序是否已打開串口
PurgeComm (m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT |PURGE_TXABORT);
for(;;) //只要所要監控的串口有線程在運行,就一直處于監視端口行為的無限循環
{
bResult = WaitCommEvent(m_hComm,&Event,&m_ov); // m_ov是OVERLAPPED類型的成員變量
if(! bResult)
{//進行相關的出錯處理的具體函數調用過程。這里與主題無關,略去不表述
}
else
{
Event = WaitForMultipleObjects(4, m_hEvent, FALSE, INFINITE);
//無限等待設定的事件發生,其中m_hEvent根據需要設定了須響應的接收、發送、關閉串口事件以及OVERLAPPED類型的hEvent事件
Switch(Event)
{//串口進行數據讀寫事件的響應處理過程。這里與主題無關,略去不表述
}
return 0;
}
在編寫遠程監控串口通訊主程序時增加上述的關鍵程序段就可實現串口通訊程序的多線程應用,從而提高串口的事件響應能力,提高遠端的數據交互實時性。
5、結束語
做為一個機房遠程監控系統的通信組成部分,該應用多線程的串口通信程序在VC++6.0中編譯通過,在以WINDOWS操作系統為廣電網絡安全管理平臺(用戶人機界面)的遠程監控管理中運行狀況良好,有效的提高了信息管理的實時性。
該程序除了具體開發的應用對象廣電網絡無人值守機房中適用,還可以推廣到相似的只要是以WINDOWS為界面管理平臺的一切遠程通信的串口管理中,提高串口通信的實時性。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -