精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于多線程技術VisualC++實現工控系統的設計

電子設計 ? 來源:電子技術應用 ? 作者:齊文,王勇前 ? 2020-10-15 17:51 ? 次閱讀

多線程技術的引入,不僅可以挖掘潛在的CPU空閑時間,而且還可以提高應用程序的反應速度,其優點在有多個任務需要完成、有巨大數據流量的程序中反映得尤為明顯。而隨著VisualC++的引入,其靈活的線程實現機制使得程序員從繁瑣的Windows編程中解脫出來。關于多線程基本機理和實現方法近年來有許多文章介紹,這里不再贅述。本文將側重于比較在工控程序中采用各種線程類型和同步方法的優劣,并給出一個實用的、有較廣適應性的程序主體框架。

1 各種線程類型和同步方法

1.1 線程類型

Visual C++中線程分為工作者線程(Worker Thread)和用戶界面線程(User Interface Thread)兩大類。

用戶界面線程的特點是擁有單獨的消息隊列,可以具有自己的窗口界面,能夠對事件和用戶輸入做出響應,具體實現時由CWinThread派生出一個類。但其缺點是當需要停止或撤銷當前正在運行的線程而向其發送中止消息后,只有在消息隊列中排在前面的消息被一一處理完之后,線程才能接受中止消息并停止當前工作,這對CPU是一種浪費,在對實時性要求較高的工控程序中是不可容忍的。

工作者線程適用于處理后臺任務,而不影響用戶對應用程序的使用。工作者線程僅僅由一個函數體實現,其實現簡單,便于編程者控制,與事件同步方法相配合能對中止消息做出較快反應。

1.2 同步方法

在多線程應用程序中,兩個或更多的線程同時訪問相同數據會導致不可預知的結果,因此保持線程間的同步是一個不可或缺的環節。VisualC++提供了四種同步方法:臨界區(Critical Section)、信號燈(Semaphore)、互斥量(Mutex)和事件(Event)。

其中采用臨界區、信號燈或互斥量進行同步時,線程間的同步過程由操作系統完全控制,系統僅僅防止多個線程對同一資源的同時使用,而相同優先級的線程對同一資源的使用順序是編程者無法控制的。而在一般工控系統中,當主控臺下方設備數據變化時,應能及時中止當前的計算(如果當前計算未完成的話)并根據新的數據開始新一輪的計算,因而要求各線程對所處理的數據有一定的操作次序。

事件同步是通過將事件自身設置為有信號或無信號來通知其它線程某一操作已完成或尚未完成,其設置可由編程人員手工完成,適合于工控程序應用。盡管事件同步方式平均效率比上面三種方式稍低,但在工控程序應用中相對于因數據未能及時更新而導致大量的無用計算及其對實時性的損害來講,還是非常值得的。

下面介紹的是參與某‘九五’預研項目中所設計的主控臺程序的基本框架,這個程序框架應能適用于大多數工控系統的主控程序。

2 軟件框架

一般工控系統的主控部分通常所必須完成的兩件事是

1)通過通信端口與下端設備通信,接收下端設備傳來的數據或向下端設備發送指令;(2)對下端設備所傳數據進行處理。

與之相對應,該軟件具有一個主線程和兩個子線程,其中一個子線程為通信線程,另一個為計算線程。主線程是Windows下每個應用程序都具備的,負責線程間的同步、向計算線程和通信線程傳遞參數、管理人機界面、接收用戶輸入、數據庫的操作和管理等功能。通信線程通過通信端口(可以是串口、并口或網絡接口等)負責與下端的設備進行通信并交換數據,當存在多級控制結構時,還可用來與更高一級的控制設備進行通信并向上傳遞數據。計算線程負責核心算法的實現,根據系統的不同完成不同的數據處理任務。程序結構如圖1。

基于多線程技術VisualC++實現工控系統的設計

進程開始后先由主線程建立通信線程與計算線程。通信線程監視通信端口,當下方設備發來數據時,就向主線程發送自定義的WM_USER_COMM_NOTIFY消息,通知主線程計算數據有所改變,主線程則對之進行處理,即中止當前的計算,并重新開始計算。

3 具體實現

用Visual C++的AppWizard生成一個應用程序,這是主控程序的雛形,該應用程序暫取名為CtrSys,后面程序名都以此為準。

3.1 多線程的定義及生成

3.1.1 多線程的定義

向項目中加入threads.cpp文件,在該文件中寫入通信線程和計算線程的控制函數。

控制函數有下面的原型:

UINT MyThreadProc(LPVOID lpvThreadParam);

lpvThreadParam參數是32位的值,這個值就是在線程對象產生時傳遞給線程構造函數的參數。控制函數能解釋此值的不同表現方式。它可以被當作一個普通變量對待,也可以被視為一個指向包含有多個參數的結構指針,也可以被忽略。如果參數指向一個結構,這個結構可能不僅僅用來從調用者傳遞參數給線程,還可能用來從線程回傳數據給調用者。如果使用這樣的結構回傳給調用者,結果準備好后線程需要通知調用者。

控制函數終止時,應該返回一個UINT類型的值,表明終止的原因。返回碼0表示成功,其它值表示不同類型的錯誤,這完全依賴實現情況。

按一般程序示例,線程通常在視類或框架窗口類中產生。但在工控程序中,通信與計算線程常常要大量地對計算數據進行操作,根據文檔/視的程序框架結構,文檔類常常用來存儲所要處理的數據。因此把計算與通信線程放在文檔類中產生,并把產生線程的當前文檔對象的指針作為線程控制函數的參數傳遞給線程。

從而,在控制函數(CalcThreadProc ()和CommThreadProc())一開始,就要對所傳來的參數進行識別:

CCtrsysDoc* pDoc = (CCtrsysDoc*)pParam;

注意要在文件開頭包括進文檔類的頭文件

#include ″CtrsysDoc.h″

3.1.2 多線程的產生

在文檔類的構造函數中產生線程。程序啟動時生成文檔對象,同時啟動兩個線程。

////////////////////////////////////

// CCtrsysDoc construction/destruction

CCtrsysDoc::CCtrsysDoc()

{

……

m_pCalcThread=AfxBeginThread(CalcThreadProc, this);

m_pCommThread=AfxBeginThread(CommThreadProc, this);

}

注意不要用Win32的CreateThread()建立線程,而應該用AfxBeginThread()函數,否則所建立的線程不能訪問其它MFC對象。

3.2 線程間的同步

程序中設置有八個事件用于線程同步:

HANDLE m_hEventPost; //用來允許通信線程向主框架

發送WM_USER_COMM_NOTIFY消息

HANDLE m_hEventStartCalc; //主框架通知計算線程開始計算

HANDLE m_hEventCalcStarted; //計算線程通知主框架計算已經開始

HANDLE m_hEventStopCalc; //主框架通知計算線程中止計算

HANDLE m_hEventCalcStopped; //計算線程通知主框架計算已經中止

HANDLE m_hEventCalcDone; //計算線程通知主框架計算已經結束

HANDLE m_hEventUpdateSourceData; //主框架通知計算線程更新數據

HANDLE m_hEventSourceDataUpdated; //通信線程通知主框架數據已更新完畢

這八個事件是主線程和兩個子線程之間同步所必需的,讀者可根據自己程序的需要另行添加。

因各線程都以文檔對象指針為參數,這些事件都在文檔類頭文件中定義,這些事件在文檔類的構造函數中生成并賦初值。

CCtrsysDoc::CCtrsysDoc()

{

……

m_hEventPost=CreateEvent(NULL,TRUE,TRUE, NULL);

m_hEventCalcDone=CreateEvent(NULL,TRUE,FALSE, NULL);

m_hEventCalcStarted=CreateEvent(NULL,TRUE,FALSE,NULL);

m_hEventStartCalc=CreateEvent(NULL, TRUE,FALSE, NULL);

m_hEventSourceDataUpdated=CreateEvent(NULL,TRUE,FALSE, NULL);

m_hEventUpdateSourceData=CreateEvent(NULL,TRUE,FALSE, NULL);

m_hEventCalcStopped=CreateEvent(NULL,TRUE,FALSE, NULL);

m_hEventStopCalc=CreateEvent(NULL, TRUE,FALSE, NULL);

……

}

線程的同步工作主要在主框架CMainFrame類的WM_USER_COMM_NOTIFY消息響應函數OnCommNotify中進行。當下方通信設備參數改變時,通信線程發送給CMainFrame類一個WM_USER_COMM_NOTIFY消息。CMainFrame類接收到消息后,在消息響應函數OnCommNotify中終止計算線程的當前計算,計算成功終止后由通信線程更新計算所需的數據源,待更新完畢后,重新開始計算。線程同步部分流程如圖2。

3.3 通信線程

通信線程部分流程如圖3所示。

3.4 計算線程

編程者應根據數據處理過程,在運算量較大或循環次數較多的地方設置對m_hEventStopCalc事件的查詢。當數據發生更新時,使用其它線程類型和同步方法往往必須等到數據處理部分結束,這樣整個一次數據處理都是無用計算;而采用上述方法,因數據更新所造成的無用計算僅僅是一步循環或幾行指令,相比而言,所導致的延時和CPU浪費是微不足道的。

計算線程部分流程如圖4所示。

責任編輯:gt

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 應用程序
    +關注

    關注

    37

    文章

    3198

    瀏覽量

    57364
  • 工控系統
    +關注

    關注

    1

    文章

    98

    瀏覽量

    14501
  • 線程
    +關注

    關注

    0

    文章

    501

    瀏覽量

    19580
收藏 人收藏

    評論

    相關推薦

    Java多線程的用法

    能力。 什么是進程 是指正在運行的程序的實例。 每個進程都擁有自己的內存空間、代碼、數據和文件等資源,可以獨立運行、調度和管理。在操作系統中,進程是系統資源分配的最小單位,是實現多任務的基礎。 Java
    的頭像 發表于 09-30 17:07 ?845次閱讀

    labview的多線程技術

    用labview開發多線程技術難道是在同一個框圖中多用幾個WHILE循環結構嗎?請玩過的大神指教
    發表于 07-25 10:33

    labview多線程技術

    labview多線程技術
    發表于 01-10 16:00

    Windows95環境下如何用VisualC++進行ODBC編程?

    Windows95環境下用VisualC++進行ODBC編程的方法及技巧是什么?
    發表于 11-11 06:18

    再談多線程技術在變電站監控系統中的應用

    介紹了Win32 中多線程技術的概念及在Delphi 開發環境中實現的方法,給出了在變電站監控系統開發中如何較好地應用多線程
    發表于 05-30 10:17 ?15次下載

    多線程技術在串口通信中的應用

            首先介紹了多線程技術的基本原理,然后討論了多線程技術在串口通信中的應用,并給出了
    發表于 09-04 09:10 ?18次下載

    基于多線程技術的連續小波變換實現

             簡要介紹了連續小波變換(CWT)的快速算法,討論了采用多線程技術編程實現CWT 的原理及方法。實驗表明,該方法可改善CW
    發表于 09-15 09:46 ?9次下載

    數控測井軟件中的多線程編程技術

    為滿足實時測井需求,提高系統資源的利用率和系統性能,在數控測井軟件開發中將多線程編程技術應用其中,并對多線程編程
    發表于 01-14 17:17 ?32次下載

    Delphi教程_實現多線程共享探測

    Delphi教程實現多線程共享探測,很好的Delphi學習資料。
    發表于 03-16 14:59 ?3次下載

    基于OPC技術多線程數據采集系統實現_喬富強

    基于OPC技術多線程數據采集系統實現_喬富強
    發表于 01-12 19:56 ?1次下載

    linux多線程編程技術

    1 引言 線程(thread)技術早在60年代就被提出,但真正應用多線程到操作系統中去,是在80年代中期,solaris是這方面的佼佼者。傳統的 Unix也支持
    發表于 10-24 16:01 ?5次下載

    什么是多線程編程?多線程編程基礎知識

    摘要:多線程編程是現代軟件技術中很重要的一個環節。要弄懂多線程,這就要牽涉到多進程。本文主要以多線程編程以及多線程編程相關知識而做出的一些結
    發表于 12-08 16:30 ?1.2w次閱讀

    如何實現VisualC++與MATLAB接口進行混合編程詳細方法說明

    本文首先論述了VisualC++和Matab混合編程的重要性和優點,介紹了在Visualc++中利用Matlab引擎調用Matab函數的方法,和在Matlab中調用Visual C ++代碼的方法
    發表于 07-16 17:09 ?20次下載

    SpringBoot實現多線程

    SpringBoot實現多線程
    的頭像 發表于 01-12 16:59 ?1710次閱讀
    SpringBoot<b class='flag-5'>實現</b><b class='flag-5'>多線程</b>

    java實現多線程的幾種方式

    Java實現多線程的幾種方式 多線程是指程序中包含了兩個或以上的線程,每個線程都可以并行執行不同的任務或操作。Java中的
    的頭像 發表于 03-14 16:55 ?440次閱讀