1. 程式人生 > >從QProcess說開來(二)

從QProcess說開來(二)

QIODevice派生類

QProcess作為QIODevice的派生類,實現角度上看,它必須要重新實現下面兩個成員函式:

  • readData()
  • writeData()

而後,按照QIODevice的常規用法,我們

  • 呼叫QIODevice::open()開啟裝置
  • 使用QIODevice::read()/QIODevice::write()讀寫
  • 使用QIODevice::close()關閉

實際上,我們的常規用法是:

常用程式碼

其呼叫父類成員

QProcess::start()

QIODevice::open()

QProcess::readAllStandardError()

QIODevice::readAll()

QProcess::readAllStandardOutput()

QProcess::write()

QIODevice::write()

QProcess::close()

QIODevice::close()

除此以外,QProcess還有靜態成員函式可用:

  • QProcess::execute() 啟動一個程序,然後等待該程序結束。
  • QProcess::startDetached() 啟動一個程序,然後使其和當前程序脫離程序的父子關係。

不過:這兩種用法應該和QIODevice的提供的功能關係不大了。

啟動

我只有ubuntu和windows系統,下面的內容也就不會超出這兩個系統的範圍。 dbzhang800 20110116

Unix

系統的2個api函式與此有關:

fork()

用來建立新程序

linux下的api函式clone()有類似功能,似乎主要用於構建執行緒

execve()

用來執行新程式

它還有5個馬甲(庫函式)
execl() execv()
execlp() execvp()
execle()

這個execve()對我們使用QProcess應該比較重要,因為我們啟動引數都是要傳遞給它的:

int execve(const char *filename, char *const argv[], char *const envp[]);

filename

如果包含“/”,則視為路徑名;否則按照PATH環境變數指定的目錄進行搜尋。filename可以是直譯器檔案(首行是#!/usr/bin/python這種)

argv

命令列引數列表

envp

環境變數列表。比如:有時可能會考慮像Windows那樣將當前路徑也加入PATH環境變數

而 QProcess::startDetached() 在Unix下建立的是一個孤兒程序:

  • 當前程序P下 fork() 得到子程序 C1
  • C1下 fork() 得到 子子程序 CC1
  • C1自願結束,CC1呼叫execve執行外部程式且與程序P脫離關係

在Unix下,還有system()、popen()等庫函式也可以用來啟動外部程式。

Windows

和Unix下完全不同,Windows程序建立的api函式是一個帶有眾多引數的CreateProcess

BOOL CreateProcess(
  PCTSTR pszApplicationName,
  PTSTR pszCommandLine,
  PSECURITY_ATTRIBUTES psaProcess,
  PSECURITY_ATTRIBUTES psaThread,
  BOOL bInheritHandles,
  DWORD fdwCreate,
  PVOID pvEnvironment,
  PCTSTR pszCurDir,
  PSTARTUPINFO psiStartInfo,
  PPROCESS_INFORMATION ppiProcInfo);

看著就頭大,看個小例子吧:

STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
TCHAR commandLine[] = TEXT("notepad.exe");

CreateProcess(NULL, commandLine, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);

只看一個單純和啟動有關的(即和前面的fork/execve引數對應的):

  • PCTSTR pszApplicationName

按照Windows核心程式設計一書中說法,99%的情況下,我們都是直接傳遞一個NULL給它。它存在的原本目的是為了支援Windows的posix子系統。

如果指定了這個引數:程式名字尾必須指定;而且不在當前工作路徑下的話,必須指定全路徑。

注:Qt在WindowCE下的實現在使用這個引數。

  • PTSTR pszCommandLine

如果前一個引數為NULL,則該字串引數中第一個空格(被雙引號括住的不算)前的內容則為應該程式的程式名。

如果程式名不包含路徑,則按照下列順序查詢:

  • 當前程序的程式檔案的所在目錄
  • 當前程序的工作目錄
  • Windows的system32目錄
  • Windows目錄
  • 環境變數PATH中的目錄

注意,這是一個字串。而在unix下,是一個字串的列表。所在當引數中包含空格等東西時,在Windows下總是需要特殊處理。

  • PVOID pvEnvironment

環境變數

  • PCTSTR pszCurDir

指定工作目錄,這個前面沒提到。因為在unix下,分成fork()/execve()兩個階段,在fork()之後直接呼叫chdir設定程序的工作目錄即可。

同樣,看一下 QProcess::startDetached()的情況:

BOOL bInheritHandles

QProcess::startDetached()

FALSE

父程序CreateProcess後立即呼叫CloseHandle關閉持有的子程序的執行緒和程序控制代碼

QProcess::start()

TRUE

程序終止

看完啟動,簡單看看終止(termination)。

在C1X和C++11標準之前,C/C++標準中沒有執行緒相關的東西 。於是和程序終止相關的函式比較簡單:

  • main 函式中的 return
  • exit()
  • _Exit()
  • abort()

接下來也不考慮多執行緒的情況(因為我理不太清)。這樣一來,只用簡單考慮:

  • 程序自願結束
  • 其他程序要求該程序結束

自願結束的我們一般不關心,所以只能後一個。在QProcess中,則對應:

  • QProcess::kill()
  • QProcess::terminate()
  • QProcess::close()

其中 QProcess::close() 呼叫 QProcess::kill()

unix

在unix下,這是通過kill傳送訊號實現的

int kill(pid_t pid, int sig);

QProcess::kill()

傳送 ::kill(pid, SIGKILL)

QProcess::terminate()

傳送 ::kill(pid, SIGTERM)

程序結束後,會向其父程序傳送 SIGCHLD 訊號。父程序呼叫wait函式來獲取程序該狀態

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

windows

Windows下程序終止的api函式是

BOOL TerminateProcess(HANDLE hProcess, UINT  fuExitCode);

QProcess::kill()呼叫是該函式。而QProcess::terminate()採用的卻是另一個東西

  • 採用 EnumWindows() 列舉程序內各個頂級視窗

  • 對各個視窗使用 PostMessage() 傳送 WM_CLOSE 訊息

  • 使用 PostThreadMessage() 對其主執行緒傳送 WM_CLOSE 訊息

FROM: http://blog.csdn.net/dbzhang800/article/details/6877762

相關推薦

QProcess開來()

QIODevice派生類 QProcess作為QIODevice的派生類,實現角度上看,它必須要重新實現下面兩個成員函式: readData()writeData() 而後,按照QIODevice的常規用法,我們 呼叫QIODevice::open()開啟裝置使用Q

QProcess開來(一)

QProcess類的作用是啟動一個外部的程式並與之互動。我們不妨看看:一個普通的控制檯程式,與外界是如何互動的 簡單控制檯程式 一個程式如何從外界獲取資訊並向外輸出資訊呢? 方向 途徑 獲取 命令列引數 in

深入Vue.js原始碼開始()

從入口開始 我們之前提到過 Vue.js 構建過程,在 web 應用下,我們來分析 Runtime + Compiler 構建出來的 Vue.js,它的入口是 src/platforms/web/entry-runtime-with-compiler.js: 摘選entry-runtime-with-co

[LeetCode] Construct Binary Tree from String 字串建立叉樹

You need to construct a binary tree from a string consisting of parenthesis and integers. The whole input represents a binary tree. It contains an integ

Android 維碼生成,掃描,近距離識別優化,相簿選擇維碼識別

做了一個二維碼掃描圖片,主要是掃描不出來,看到一篇部落格,其中的第二種方法可以掃描到,在此做筆記,以備後用,前面的進入相簿,返回,到獲取圖片路徑方法都一樣; (1):二維碼生成的方法順便貼上: private Bitmap createQRImage(String url, final

199. Binary Tree Right Side View | 右邊看叉樹得到的集合

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to b

Mac中Jenkins自動打包上傳fir的配置流程(零開始)

二.配置Jenkins 1.初始化 安裝完成後,開啟瀏覽器,輸入 http://localhost:8080 會出現下圖的重設初始密碼的介面 找到/Users/Shared/Jenkins/Home/資料夾,更改裡面secrets資料夾及其中init

C語言---指標到重指標(上)

江湖傳言:得指標者得C語言。不知道這句話是從什麼時候開始流傳的,不過這也不重要,重要的是我們隱約能從中感受到指標在C語言中的重要性。對於初學C語言的人來說,指標可能是大多數人心中的痛。筆者當年學C語言的時候在指標這塊還算順利,自以為已經熟練掌握了指標,等到後來學習資料結構的時

Android 基於Zxing掃碼實現(三)、相簿選取維碼

前言 本文的程式碼基於YZxing庫,如需查閱程式碼可前往GitHub上面檢視。專案地址如下: YZxing 內容 從相簿獲取二維碼,主要涉及到幾大步驟。 第一,進入相簿獲取照片。 第二,對照片進行壓縮。 第三,對照片上的二維碼進行de

EF Core 原理原始碼出發()

緊接著我的上一篇部落格,可以點選這裡回到上一篇部落格,上回分析到ef 一個重要的物件,changetracker這個物件,當我們向DbContext新增物件的時候我們會呼叫如下程式碼。 1 private EntityEntry<TEntity> SetEntityState&

零開始構建一個的asp.net Core 項目(

mage .... cfi web execute 運行 figure 今天 deb 接著上一篇博客繼續進行。上一篇博客只是顯示了簡單的MVC視圖頁,這篇博客接著進行,連接上數據庫,進行簡單的CRUD。 首先我在Controllers文件夾點擊右鍵,添加->控制器 彈

零開始學習html(十)CSS布局模型——下

位操作 女生 margin 沒有 定位元素 top 並且 變化 開始 五、什麽是層模型? 什麽是層布局模型?層布局模型就像是圖像軟件PhotoShop中非常流行的圖層編輯功能一樣, 每個圖層能夠精確定位操作,但在網頁設計領域,由於網頁大小的活動性,層布局沒能受到熱捧。 但是

rnn到lstm,再到seq2seq(

app 感受 ima bsp expand images cat https github 從圖上可以看出來,decode的過程其實都是從encode的最後一個隱層開始的,如果encode輸入過長的話,會丟失很多信息,所以設計了attation機制。 attati

性能測試0到1的過程(

sleep efi python腳本 size sel 應用服務器 完全 展示 服務   本人,從畢業開始接觸測試,但是性能方面一無所知。之前在第一份工作,測過安卓客戶端,當時寫過一個非常簡單的shell腳本,push到手機系統內,用於手機硬件信息。但是在服務端的性能方面,

(轉)Python的0.1輸出0.1000000000000001說浮點數的進制

python2 comment 科學 交換 tps alt 三種 一段 fill 原文地址:http://blog.csdn.net/u012843100/article/details/60885763 今天在學習Python核心編程的時候,十進制浮點數那段看到一個有趣的

cocos2dx 3.1零學習()——菜單、場景切換、場景傳值

天空 ptr select 特效 new 要點 綁定 使用 water 回想一下上一篇的內容,我們已經學會了創建一個新的場景scene,加入sprite和label到層中。掌握了定時事件schedule。我們能夠順利的寫出打飛機的主場景框架。 上一篇的內容我練習了七個新

劍指offer之【上往下打印叉樹】

emp pub push coder 二叉 spa cti public ott 題目:   從上往下打印二叉樹 鏈接:   https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13

零開始學Xamarin.Forms() 環境搭建、創建項目

官方 log targe 4.4 pad jdk 新建文件夾 ini pos 一、環境搭建 Windows下環境搭建: 1.下載並安裝jdk 、Android SDK和NDK。當然還須要 VS2013 update 2(VS2010、VS2012均可)以上

如何維數組中的多個key中獲取指定key的值?

福建 ava 而且 標簽 column spa com school itl 精華 LOVEME96 2016-10-21 10:40:19 瀏覽(1512) 回答(3) 贊(0) 新手求教:二維數組中一般會有多個key,如果我們要獲得指定key的值,應

進制數據流中構造GDAL能夠讀取的圖像數據

數據 delet seek emf width set content 讀取 折騰 在非常多時候。我們的圖像數據往往都不是文件方式存儲在磁盤上。而是可能從網絡或者數據庫中獲取的是二進制的圖像數據流。最簡單的方式和最easy想到的方式就是將這個文件流保存到磁盤上形成一個文