1.最簡單的,我們可以通過system直接啟動一個應用程序或者腳本:(但是要調用 #include <stdlib.h>)
system("./helloworld"); //可以直接運行可執行文件
system("./hello.sh"); //也可以直接運行腳本
技巧: system 函數參數是char* 如果正確返回0。
2. 操作簡單,但是我們可以很清晰的看到弊端:雖然很順利的匹出一個進程去執行另外一個應用,但是我們拿不到這個新進程的任何東西,也就失去了對這個進程的控制權。所以我們可以嘗試利用QProcess:
QProcess *workPacePath = new QProcess(); workPacePath->start("pwd"); connect(workPacePath,SIGNAL(readyReadStandardOutput()) ,this, SLOT(workPacePathSlot()) );
這樣就能通過槽函數讀取第三方可執行程序的輸出了(但是前提 workPacePath設置全局的)
void MainWindow::workPacePathSlot() { QString workPacePathTemp = workPacePath->readAll(); Singleton::workPacePathGlobal =workPacePathTemp.mid(0,workPacePathTemp.length()-8); // /home/alvin/code/keysiQt/ qDebug() << "工作空間:" << Singleton::workPacePathGlobal << endl; }
拿到proc指針,我們可以做一些我們想做的事情。做嵌入式應用編程的朋友可能時常會受到環境變量的困擾,很納悶為什么總是找不到這庫那庫。所以我們可以再完善一下:
QProcess *proc = new QProcess(); proc->setEnvironment(proc->environment()); proc->start(str); proc->waitForStarted();
如果我們想要執行的腳本需要傳參呢?我們有必要完善一下參數列表:
QString program = "./hello.sh"; QStringList arguments; arguments << str; QProcess *myProcess = new QProcess(); myProcess->start(program, arguments);
項目中,我們經常遇到這樣的情況:模塊一單獨工作正常,模塊二單獨工作也正常,但是整合到一起,在特定的環境下就出這樣那樣的問題。舉一個啟動應用程序的例子:進程間通信很容易出錯,進程A發送啟動helloworld的消息給進程B,進程B接到消息就啟動helloworld。進程A只發送一次消息,但是進程B卻接到2個發送任務,連續啟動2個helloworld,這種錯誤很致命,尤其是在內存緊張的環境下,但是的確不容易排查。所以,為了避免悲劇的發生,哪怕我們不能准確的定位進程間通信的錯誤根源,聰明的程序員依舊可以解決這個問題:
system("ps | grep helloworld |grep -v grep || ./helloworld &");
如果你還不熟悉腳本語言,那么我很樂意解釋一下:ps查看系統進程信息,grep檢索一下helloworld相關的進程,然后排除掉grep本身這個進程,如果已經存在一個helloworld,那么不進去執行,如果沒有存在helloworld,就啟動一個helloworld。即完成了單一啟動保護處理。
如果你需要必須保證啟動一個新的helloworld,那么依舊有好辦法,先殺掉可能存在的helloworld,然后再啟動,無聲無息:
system("killall helloworld");
如果不確定應用名字就是helloworld,我們只需要把命令替換成:
ps aux | grep helloworld | grep -v grep |awk '{print $2}' | xargs kill 2&> /dev/null
需要提醒的是,根據ps的輸出,找到pid那一列,如果在第一列,則改成print $1 ,Busybox可能會存在差異所以要注意
