使用winAPI串列埠通訊 二

2021-05-06 08:38:40 字數 4055 閱讀 5265

採用同步方式的查詢方式讀取串列埠資料時,若由於串列埠操作耗費較長的時間,則程式會被掛起.為解決這種問題,可以在讀取資料時採用重疊i/o操作.此時,讀寫資料的操作在單獨的執行緒 中進行,發出讀寫要求的主線程可以繼續執行.當讀寫資料成功後,讀寫資料線程可以通過某種方式通知主線程.兩個執行緒協調工作 ,可以明顯提高程式的效率.

為了實現重疊i/o操作,主要有如下幾個程式設計步驟:  定義全域性變數、建立串列埠、發出讀寫操作、讀寫執行緒函式的建立、關閉串列埠等.

1. 定義全域性變數

handle     hcom;          //串列埠控制代碼

dword    threadprocwrite(lpvoid  pparam);       //寫執行緒函式

dword    threadprocread(lpvoid  pparam);      //讀執行緒函式

handle    hthreadwrite;         //寫執行緒控制代碼

handle    hthreadread;        //讀執行緒控制代碼

hwnd     hwnd;        //視窗控制代碼

2. 建立串列埠

hcom = createfile ( "com2",

generic_read | generic_write, 0,

null,

open_existing,

null );

if( hcom != invalid_handle_value)

else

hwnd = getsafehwnd();          //獲取當前視窗的控制代碼

3. 發出讀寫操作

(1) 讀操作

在讀操作中,只是啟動讀執行緒.實際的讀操作在讀執行緒函式中完成.

dword    dwthreadid;

dword    dwparam;

hthreadread = createthread ( null, 0,

(lpthread_start_routine)threadprocread,

&dwparam,

0,       //建立執行緒後,立即執行該執行緒

&dwthreadid);

if(hthreadread==null)

createthread()函式用於建立乙個執行緒.

handle   createthread (

//執行緒安全屬性,null表示該執行緒不能被繼承

lpsecurity_attributes     lpthreadattributes,

//初始化棧大小.0表示預設值或按呼叫棧執行緒配置

dword     dwstacksize,

//執行函式名稱

lpthread_start_routine      lpstartaddress,   

lpvoid   lpparameter,           //向新執行緒傳遞的引數

dword   dwcreationflags,     //建立標誌.0表示建立後立即執行 

lpdword     lpthreadid );

(2) 寫操作

在寫操作中,同樣只是啟動寫執行緒.實際的寫操作在寫執行緒函式中完成.

dword    dwthreadid;

dword    dwparam;

hthreadwrite = createthread( null, 0,

(lpthread_start_routine)threadprocwrite,

&dwparam, 0,

&dwthreadid);

if(hthreadwrite==null)

4.讀寫執行緒函式的建立

讀寫的實際操作在讀寫執行緒函式中執行. 這兩個函式都是全域性函式.

(1) 讀執行緒函式

在讀執行緒函式中,首先應初始化重疊結構rol的成員 hevent,將其設定為無訊號狀態.當讀操作完成或出現通訊錯誤時,該變數會被自動設定為有訊號狀態.接下來就可以使用readfile()函式發出讀 命令.若該讀函式返回true,說明讀操作已經完成,可以處理讀取的資料.若該讀函式返回false,說明讀操作未完成.此時使用 waitforsingleobject()函式等待讀操作的結構。根據返回結果的不同,採取相應的處理**即可.

dword     threadprocread(lpvoid   pparam)

if (readfile (hcom,         //串列埠控制代碼

&mybyte,     //存放讀取資料

3,         //要讀取的位元組數

null,

&rol) )       //指向建立hcom時的rol的指標

else

else

break;

case   wait_timeout:

//讀操作失敗,原因是超時

break;

default:

//這裡加入預設處理**

break; }

}closehandle(rol.hevent);

return 0; }

createevent() 函式用來建立乙個事件控制代碼,並設定其訊號狀態.

handle    createevent (

//事件安全屬性,null表示該事件控制代碼不能用於繼承

lpsecurity_attributes   lpeventattributes,

bool    bmanualreset,    //true表示該事件需人工復位

bool    binitialstate,   //事件物件的初始狀態,true表示有訊號,反之無訊號

lpctstr    lpname       //指向事件物件的名稱,null表示建立乙個無名事件物件 );

readfile()函式是讀緩衝區命令,若該命令執行後返回true,說明已經讀成功. 若該命令返回false,說明該命令返回時,讀操作尚未完成,讀操作繼續在後台中進行. 此時使用waitforsingleobject()函式來獲取後台 讀命令的操作結果. 

dword    waitforsingleobject (

handle     hhandle,       //指向等待物件的控制代碼

dword     dwmilliseconds,       //超時時間 );

handle      hfile,           //指向串列埠控制代碼

lpdword    lpnumberofbytestransferred,     //存放實際讀出位元組數量變數的位址

bool     bwait      //設為true表示讀操作完成該函式才返回,若為false表示如果操作未完成時函式將返回false. );

(2) 寫執行緒函式

寫執行緒函式所作操作與讀執行緒函式的操作相似.首先初始化 wol的hevent事件成員,然後發出寫命令writefile().若該寫命令返回true,說明寫操作成功完成.若寫命令返回false,說明寫操 作沒有完成.使用waitforsingleobject()函式等待寫操作的結果,根據返回結果的不同,採取相應的處理**.

dword     threadprocwrite(lpvoid   pparam)

if (writefile (hcom,         //串列埠控制代碼

&mybyte,     //存放待傳送資料

3,         //欲傳送的位元組數

null,

&wol) )       //指向建立hcom時的wol的指標

else

else

break;

case   wait_timeout:

//讀操作失敗,原因是超時

break;

default:

//這裡加入預設處理**

break; }

}closehandle(wol.hevent);

return 0; }

5. 關閉串列埠

使用closehandle()函式關閉串列埠控制代碼.

使用winAPI串列埠通訊 二

採用同步方式的查詢方式讀取串列埠資料時,若由於串列埠操作耗費較長的時間,則程式會被掛起.為解決這種問題,可以在讀取資料時採用重疊i o操作.此時,讀寫資料的操作在單獨的執行緒中進行,發出讀寫要求的主線程可以繼續執行.當讀寫資料成功後,讀寫資料線程可以通過某種方式通知主線程.兩個執行緒協調工作,可以明...

使用winAPI 串列埠通訊 一

串列埠和其他通訊裝置是作為檔案處理的.簡單的可以採用查詢方式 定時方式 複雜些的可以採用事件驅動的方式.所謂驅動方式,即當有序列資料進入輸入緩衝區時,自動執行接受程式.使用winapi來編寫 串列埠通訊程式時,讀寫操作可以有同步方式與重疊的非同步方式.所謂同步方式,就是當命令發出後,直到資料確實寫入...

串列埠通訊方法(WINAPI實現)

前言 程式實現 我在經過許多的專案的開發和實踐中發現,採用win api函式進行串列埠的開發能夠給程式設計師很大的控制項,並且程式運也很穩定。所以我將與串列埠接觸的函式進行封裝,然後在各個工程中進行呼叫,效果還是比較好的,現將各個函式和呼叫方法列舉出來,希望對各位有所幫助。一 設定串列埠相關工作 d...