採用同步方式的查詢方式讀取串列埠資料時,若由於串列埠操作耗費較長的時間,則程式會被掛起.為解決這種問題,可以在讀取資料時採用重疊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()函式關閉串列埠控制代碼.
closehandle(hcom);
使用winAPI串列埠通訊 二
採用同步方式的查詢方式讀取串列埠資料時,若由於串列埠操作耗費較長的時間,則程式會被掛起.為解決這種問題,可以在讀取資料時採用重疊i o操作.此時,讀寫資料的操作在單獨的執行緒 中進行,發出讀寫要求的主線程可以繼續執行.當讀寫資料成功後,讀寫資料線程可以通過某種方式通知主線程.兩個執行緒協調工作 可以...
使用winAPI 串列埠通訊 一
串列埠和其他通訊裝置是作為檔案處理的.簡單的可以採用查詢方式 定時方式 複雜些的可以採用事件驅動的方式.所謂驅動方式,即當有序列資料進入輸入緩衝區時,自動執行接受程式.使用winapi來編寫 串列埠通訊程式時,讀寫操作可以有同步方式與重疊的非同步方式.所謂同步方式,就是當命令發出後,直到資料確實寫入...
串列埠通訊方法(WINAPI實現)
前言 程式實現 我在經過許多的專案的開發和實踐中發現,採用win api函式進行串列埠的開發能夠給程式設計師很大的控制項,並且程式運也很穩定。所以我將與串列埠接觸的函式進行封裝,然後在各個工程中進行呼叫,效果還是比較好的,現將各個函式和呼叫方法列舉出來,希望對各位有所幫助。一 設定串列埠相關工作 d...