日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

qprocess回调_QT进程间通信详细介绍及QProcess机制分析

發布時間:2023/12/15 c/c++ 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qprocess回调_QT进程间通信详细介绍及QProcess机制分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、QT通信機制

為了更好的實現QT的信息交互,在QT系統中創建了較為完善的通信機制。QT的通信可分為QT內部通信和外部通信兩大類。對于這兩類通信機制及應用場合做如以下分析:

(1)QT內部對象間通信

在圖形用戶界面編程中,經常需要將一個窗口部件的變化通知給窗口的其它部件使其產生相應的變化。對于這種內部對象間的通信,QT主要采用了信號和槽的機制。這種機制是QT區別于其他GUI工具的核心機制。在大部分的GUI工具中,通常為可能觸發的每種行為通過定義回調函數來實現。這種回調函數是一個指向函數的指針,在進行函數回調執行時不能保證所傳遞的函數參數類型的正確性,因此容易造成進程的崩潰。

在QT中,信號和槽的機制取代了這種繁雜的、易崩潰的對象通信機制。信號是當對象狀態改變時所發出的。槽是用來接收發射的信號并響應相應事件的類的成員函數。信號和槽的連接是通過connect()函數來實現的。例如,實現單擊按鈕終止應用程序運行的代碼

connect(button , SIGNAL(clicked()) , qApp , SLOT(quit()) );實現過程就是一個button被單擊后會激發clicked信號,通過connect()函數的連接qApp會接收到此信號并執行槽函數quit()。在此過程中,信號的發出并不關心什么樣的對象來接收此信號,也不關心是否有對象來接收此信號,

只要對象狀態發生改變此信號就會發出。此時槽也并不知曉有什么的信號與自己相聯系和是否有信號與自己聯系,這樣信號和槽就真正的實現了程序代碼的封裝,提 高了代碼的可重用性。同時,信號和槽的連接還實現了類型的安全性,如果類型不匹配,它會以警告的方式報告類型錯誤,而不會使系統產生崩潰。

(2)QT與外部設備間通信

QT與外部通信主要是將外部發來的消息以事件的方式進行接收處理。外部設備將主要通過socket與QT應用程序進行連接。在此,以輸入設備與QT應用程序的通信為例說明QT與外部通信的原理。

在QT的應用程序開始運行時,主程序將通過函數調用來創建并啟動qwsServer服務器,然后通過socket建立該服務器與輸入硬件設備的連 接。服務器啟動后將會打開鼠標與鍵盤設備,然后將打開的設備文件描述符fd連接到socket上。等到QT應用程序進入主事件循環時,事件處理程序將通過 Linux系統的select函數來檢測文件描述符fd的狀態變化情況以實現對socket的監聽。如果文件描述符fd狀態改變,說明設備有數據輸入。此 時,事件處理程序將會發出信號使設備輸入的數據能及時得到QT應用程序的響應。數據進入服務器內部就會以事件的形式將數據放入事件隊列里,等待QT客戶應

用程序接收處理。處理結束后再將事件放入請求隊列里,通過服務器將事件發送到相應硬件上,完成外部輸入設備與QT應用程序的整個通信過程。

2、 QProcess機制分析

QProcess類通常是被用來啟動外部程序,并與它們進行通信的。QProcess是把外部進程看成是一個有序的I/O設備,因此可通過 write()函數實現對進程標準輸入的寫操作,通過read(),readLine()和getChar()函數實現對標準輸出的讀操作。

(1) QProcess通信機制

QT可以通過QProcess類實現前端程序對外部應用程序的調用。這個過程的實現首先是將前端運行的程序看成是QT的主進程,然后再通過創建主進 程的子進程來調用外部的應用程序。這樣QProcess的通信機制就抽象為父子進程之間的通信機制。QProcess在實現父子進程間的通信過程中是運用 Linux系統的無名管道來實現的,因此為了能更加清楚的說明QProcess的通信機制,在此首先介紹關于無名管道實現父子進程間的通信機制。

無名管道是一種只能夠在同族父子之間通信,并且在通信過程中,只能從固定的一端寫,從另一端讀的單向的通信方式。該無名管道是通過調用pipe()函數而創建的。創建代碼如下:

#include??int?pipe(int?fd[2])?; ?返回:若成功則為0,若出錯則為-1

創建后經參數fd返回兩個文件描述符:fd[0]為讀而打開,fd[1]為寫而打開。經過fork()函數創建其子進程后,子進程將擁有與父進程相 同的兩個文件描述符。如果想要實現父進程向子進程的通信則關閉父進程的讀端fd[0],同時關閉子進程的寫端fd[1]。這樣就建立了從父進程到子進程的 通信連接。

由于無名管道的單向通信性,所以如果要應用無名管道實現父子進程之間的雙向通信則至少需要應用雙管道進行通信。QProcess類的通信原理就是利 用多管道實現了父子進程之間的通信。然而對于外部運行的應用程序大都是通過標準輸入而讀得信息,通過標準輸出而發送出信息,因此只通過建立管道并不能完成 內外進程?之間的通信。要解決此問題,就如該模塊開始時所說,QProcess是把外部進程看成是一個I/O設備,然后通過對I/O設備的讀寫來完成內外 進程的通信。

在QProcess中父子進程之間是通過管道連接的,要實現子進程能從標準輸入中讀得父進程對管道的寫操作,同時父進程能從管道中讀得子進程對標準 輸出或標準容錯的寫操作,就要在子進程中將管道的讀端描述符復制給標準輸入端,將另外管道的寫端描述符復制給標準輸出端和標準容錯端,即實現管道端口地址 的重定向。這樣子進程對標準輸入、標準輸出及標準容錯的操作就反應到了管道中。

QProcess在正常渠道模式下具體實現共用了五個無名管道進行通信。五個管道的描述符分別用 childpipe[2],stdinChannelpipe[2],stdoutChannelpipe[2],stderrChannelpipe[2] 和deathpipe[2]五個數組來保存。deathpipe指代的管道會用在消亡的子進程與父進程之間。當子進程準備撤銷時會發送一個表示該子進程消 亡的字符給父進程來等待父進程進行處理。stdinChannelpipe,stdoutChannelpipe和stderrChannelpipe所

指代的管道分別與標準輸入,標準輸出和標準容錯進行綁定,實現了與外部程序的通信。childpipe指代的管道主要是為父子進程之間的通信而建立的。

如果在管道中有新數據寫入,就會通知相應進程去讀。另外圖2是QProcess在正常渠道模式下的通信原理圖,如果是在融合渠道模式下,將沒有容錯 管道,此時原理圖中將沒有第一個管道,也就不會有管道描述符。同時,標準容錯端和標準輸出端將共同掛接到子進程的stdoutChannelpipe的寫 端,來實現內外進程的通信。

(2) QProcess應用方式

由于QProcess類實現了對底層通信方式較為完善的封裝,因此利用QProcess類將更為方便的實現對外部應用程序的調用。在此,通過在QT界面中調用外部mplayer的例子來簡單說明QProcess的應用方式。

const?QString?mplayerPath("/mnt/yaffs/mplayer");

const?QString?musicFile("/mnt/yaffs/music/sound.mp3");

QProcess*?mplayerProcess=new?QProcess();

QStringList?args;

args<

args<

args?<

args?<

args<

mplayerProcess->setProcessChannelMode(QProcess::MergedChannels);

mplayerProcess->start(mplayerPath,args);

第一行指明了所要調用的外部應用程序mplayer的位置。

第二行指明了所要播放的聲音文件及目錄路徑。

第三行創建一個指向類QProcess的指針。

第四到第九行指定mplayer參數,具體參數可以查看maplayer參數介紹。

-slave參數表示打開slave模式. 這用來將MPlayer作為其它程序的后端. MPlayer將從他的標準輸入讀取簡單命令行, 而不再截獲鍵盤事件.SLAVE模式協議部分將解釋其語法。

-quiet顯示較少的輸出和狀態信息。

-wid可以為mplayer指定輸出窗口。

-af volume=10選擇輸出音量級別為10.這個選項是不可重入的, 所以對每個音頻流只能使用一次。

第十行為設置進程渠道的模式為融合模 式,即將標準輸出和標準容錯綁定到同一個管道的寫端。

第十一行為啟動外部應用程序mplayer。內核中管道及通信環境的建立都是在此步中完成的。

mplayer在slave模式下運行會自動從標準輸入中讀取信息并執行。由QProcess的通信原理可知,管道的讀端描述符

stdinChannelpipe[0]復制給了標準輸入,即標準輸入的描述符也為stdinChannelpipe[0],因此按照標準輸入的描述符去 讀信息就是到stdinChannelpipe所對應的管道中讀取信息。所以如果想在QT的主進程中發送命令使mplayer退出,只需在主程序中向 stdinChannelpipe[1]端寫入命令quit就可以,執行語句為myProcess->write(”quit ”);(此處的 write()函數為QProcess類的成員函數,具體實現就是向stdinChannelpipe[1]端寫入信息)

(3)QProcess的發展及分析

QProcess類伴隨著QT/Embedded的發展逐漸趨于完善。在QTE2及其更前版本中還沒有QProcess類,如果想實現與外部應用程 序的通信,必須要自己實現對管道或socket的建立與重定向。到了QTE3版本,就實現了對QProcess類的封裝。在QTE3的版本 中,QProcess類的實現是通過應用socket來建立主進程與外部應用程序之間通信的。通信原理與圖3所示基本相同,只是將圖中的管道描述符改為是 socket的描述符即可。QT主程序在建立成對socket描述符時需要調用Linux系統函數socketpair()。在生成的成對socket描

述符之間可以實現父子進程之間的雙向通信,即無論是socket的0套接口還是1套接口都可進行讀寫。

但為了避免出現通信過程中父子進程對同一個socket的爭奪,例如,在子進程還未將父進程發送的信息全部讀出時,子進程又要求將自己產生的數據返 回給父進程。如果父子進程雙向通信只用一個socket來完成,就會出現父子進程發送的信息混亂情況。因此,對于QProcess的實現仍然必須通過多個 socket來共同完成。

由上面的描述可知,盡管socket有雙向通信功能,但在實現QProcess過程中只是利用socket實現了單向通信功能。因此既浪費了對資源 的利用又增加了系統的開銷。為了解決此問題,QTE4版本將QProcess的通信連接方式由socket改為了只能實現單向通信的無名管道來實現。通信 原理就是以上3.1 QProcess通信機制中所描述的。

3、其它通信方式

除了上面介紹的無名管道和socket通信方式外,一般操作系統中常用的進程間通信機制也都可以用于QT系統內部不同進程之間的通信,如消息隊列、共享內存、信號量、有名管道等機制。其中信號量機制在QT中已經重新進行了封裝;有些機制則可以直接通過操作系統的系統調用來實現。另外,如果我們只是想通過管道或socket來實現較簡單的外部通信,也可以重新創建管道或socket來實現自己要求的功能。例如,還是在QT主程序中調用外部mplayer。如果我們只是想在QT主程序中控制mplayer,而不要求得到mplayer輸出的信息。則可以按照以下方式來實現:

const?char*?mplayerPath?=?"/mnt/yaffs/mplayer";

const?char*?musicFile?=?"/mnt/yaffs/music/sound.mp3";

const?char*?arg[5];

arg[0]?=?mplayerPath;

arg[1]?=?"-slave";

arg[2]?=?"-quiet";

arg[3]?=?musicFile;

arg[4]?=?NULL;

int?fd[2],pid;

if(pipe(fd)<0)

printf("creating?pipe?is?error ");

else?while((pid=fork())<0);

if(pid==0)

{

::close(fd[1]);

::dup2(fd[0],STDIN_FILENO);

execvp(arg[0],(const*?char*)arg);

}

else

{

::close(fd[0]);

}

第1到8行與前面QProcess類實現調用mplayer一樣,是用來指明mplayer運行時參數的。第10行是創建一個管道。第12行是創建一個子進程。15,20行是關閉父子進程中沒用的管道描述符。此時可結合圖2.1和圖2.2來理解從父進程到子進程通信環境的建立。第16行是把子進程的讀端與標準輸入綁定,以便mplayer能夠接收到父進程發出的命令。17行就是從子進程中調用外部mplayer的實現。此時,程序執行后,mplayer就可以運行起來。如果想在QT主程序中通過發送命令使mplayer退出,就在管道的寫端寫入命令"quit"就可以。實現語句為write(fd[1],

"quit",strlen("quit"));

該例子說明了QT通信方式運用的靈活性,可以根據實際情況進行應用。同時該例子的實現方式正是利用了QProcess類實現的機制,因此可以結合這個例子更加深刻的理解QProcess類的實現機制。

總結

以上是生活随笔為你收集整理的qprocess回调_QT进程间通信详细介绍及QProcess机制分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本一区二区三区四区在线观看 | 亚洲av无码一区二区三区性色 | 亚洲精品免费在线播放 | 国产欧美视频一区 | 国产激情一区二区三区在线观看 | 人妻丰满熟妇无码区免费 | av基地| 久久久高清视频 | 精品麻豆视频 | 一级片在线免费看 | 日欧美女人 | 97精品国产97久久久久久春色 | 亚洲在线免费看 | 美女诱惑一区二区 | 午夜三区 | xxxx黄色片| 波多野结衣在线一区二区 | 高h校园不许穿内裤h调教 | 香蕉影院在线 | 国产毛片毛片毛片毛片 | 欧美日本亚洲韩国国产 | 美女的隐私免费看 | a视频免费在线观看 | 婷婷色综合 | 国产porn| 干爹你真棒插曲免费 | 毛片看| 中国字幕av | 青青草国产一区二区三区 | 日韩精品h| 无码人妻精品一区二区三区99日韩 | 国产又大又硬又粗 | 欧美黑人一级爽快片淫片高清 | 久艹在线观看 | 精品国模一区二区三区 | 男女扒开双腿猛进入爽爽免费 | 国产极品在线观看 | 一区二区三区精品视频 | 丰满岳乱妇国产精品一区 | 一级做a爰 | 波多野结衣在线观看视频 | 高hnp视频 | 国产一区二区视频在线 | 亚洲色图美腿丝袜 | 丁香婷婷综合网 | 四虎视频国产精品免费 | 国产亚洲色婷婷久久99精品91 | 99999视频| 国产又黄又大又粗视频 | 国产18精品乱码免费看 | 日韩欧美亚 | 91亚洲精品在线 | 欧美性黄色 | 天天爱天天爽 | 黑人狂躁日本妞hd | 精品久久影院 | 乱色精品无码一区二区国产盗 | 黄色网炮| 大胸奶汁乳流奶水出来h | 成人免费视频网站在线观看 | 国产妻精品一区二区在线 | 亚洲伦理一区二区 | 五月天黄色网址 | 国产亚洲精品久久久久久 | 国产成人精品视频在线 | 精品理论片 | 日韩激情综合网 | 91学生片黄| 欧美午夜一区二区 | 欧洲自拍偷拍 | 日本黄色不卡视频 | 亚洲欧美一区二区三区久久 | 欧美毛片基地 | 中文字幕偷拍 | 91免费视频免费版 | 可以在线观看的黄色 | 这里只有久久精品 | 男性影院 | 美女视频黄免费 | 伊人久久九| 成人在线观看黄色 | 夜夜爽日日澡人人添 | 邻居少妇张开腿让我爽了在线观看 | 最新日韩视频 | 西比尔在线观看完整视频高清 | 三级电影在线看 | 三级艳丽杨钰莹三级 | 国产在线播放网站 | 激情成人综合 | 久久久999精品视频 国产在线xx | 人人精品久久 | 少妇一级淫片免费 | a级免费网站 | 色丁香综合 | 一区二区三区视频网 | 久久亚洲熟女cc98cm | 91区| 青青免费在线视频 | 国产精品无 |