Linux Qt编程——在程序中启动其他应用、脚本

上一篇 / 下一篇  2012-05-24 10:20:42 / 个人分类:Linux

我们在编程过程中,经常会遇到这样的需求,点击一下按钮,启动另外一个应用程序,或者执行一个脚本。你一定觉得这个多简单啊,有什么可写的?其实实 现同一个功能,不同的开发人员写出的代码可能千差万别,执行效率,容错率,是否有唯一启动保护等……当然,我们还是需要通过衡量具体的需求和环境来设计自 己的代码,量体裁衣。51Testing软件测试网N%y \^HA0_

  最简单的,我们可以通过system直接启动一个应用程序或者脚本:51Testing软件测试网 `3q-fvn

system("./helloworld");51Testing软件测试网u(FWR@1NV V2v
system("./hello.sh");

5O8Wr_(BJ0  操作简单,但是我们可以很清晰的看到弊端:虽然很顺利的匹出一个进程去执行另外一个应用,但是我们拿不到这个新进程的任何东西,也就失去了对这个进程的控制权。所以我们可以尝试利用QProcess:51Testing软件测试网"|ml6c z:Y:a*h

void Widget::startApps(QString str)
|Q+Y&m}Y0{
1`4r"wO*[n0    QProcess *proc = new QProcess();
-O%c7a"Z%E4Q~T0    proc->start(str); 51Testing软件测试网&Y(]'\ yC?p4pJ J
}

0X}?0f4F)S*a0  拿到proc指针,我们可以做一些我们想做的事情。做嵌入式应用编程的朋友可能时常会受到环境变量的困扰,很纳闷为什么总是找不到这库那库。所以我们可以再完善一下:51Testing软件测试网X{&D0j6g

void Widget::startApps(QString str)51Testing软件测试网Y#|z%i+Z
{51Testing软件测试网%? fwJ @/K~7|6qh@
    QProcess *proc = new QProcess();51Testing软件测试网(X:s l O"U/h U\
    proc->setEnvironment(proc->environment());
T/nrz1~ W2u,\6vW/bO0    proc->start(str);51Testing软件测试网1XS&ut Odf I
    proc->waitForStarted();51Testing软件测试网9j4Is Z3t%vZ
}

U6R-^"\k2G0  如果我们想要执行的脚本需要传参呢?我们有必要完善一下参数列表:

+Yw_H'pb:x;g0
void Widget::startSh(QString str)
r:l:x;z+P\ Q#rq/?0{51Testing软件测试网D9QlaFNq
    QString program = "./hello.sh";51Testing软件测试网)s#f+WRGo
    QStringList arguments;51Testing软件测试网2d5sudo3A"I!sRjU
    arguments << str;51Testing软件测试网^9~)Ca}I"];JS
    QProcess *myProcess = new QProcess();
r~ R Hq(m,uJ Ms!p0    myProcess->start(program, arguments);
rovz,gQMKm0}
51Testing软件测试网_8^ o*_H XO6x

  项目中,我们经常遇到这样的情况:模块一单独工作正 常,模块二单独工作也正常,但是整合到一起,在特定的环境下就出这样那样的问题。举一个启动应用程序的例子:进程间通信很容易出错,进程A发送启动 helloworld的消息给进程B,进程B接到消息就启动helloworld。进程A只发送一次消息,但是进程B却接到2个发送任务,连续启动2个 helloworld,这种错误很致命,尤其是在内存紧张的环境下,但是的确不容易排查。所以,为了避免悲剧的发生,哪怕我们不能准确的定位进程间通信的 错误根源,聪明的程序员依旧可以解决这个问题:

Y6RQ0{NDL0
system("ps | grep helloworld |grep -v grep || ./helloworld &");
51Testing软件测试网E F#E$b5n1S

   如果你还不熟悉脚本语言,那么我很乐意解释一下:ps查看系统进程信息,grep检索一下helloworld相关的进程,然后排除掉grep本身这个 进程,如果已经存在一个helloworld,那么不进去执行,如果没有存在helloworld,就启动一个helloworld。即完成了单一启动保 护处理。51Testing软件测试网8G}^[#OL

51Testing软件测试网8IpvOh!V)T5a

  如果你需要必须保证启动一个新的helloworld,那么依旧有好办法,先杀掉可能存在的helloworld,然后再启动,无声无息:51Testing软件测试网TL6x HQ]e9GX

system("killall helloworld");
51Testing软件测试网e5F$~M#v4~ _

  如果不确定应用名字就是helloworld,我们只需要把命令替换成:51Testing软件测试网5M^}7N}Eo6q+G

ps aux | grep helloworld | grep -v grep |awk '{print $2}' | xargs kill 2&> /dev/null

[9ZgaNLz S r,T*ZB0  需要提醒的是,根据ps的输出,找到pid那一列,如果在第一列,则改成print $1 ,Busybox可能会存在差异所以要注意。

5_%JuT&Y8A q0

i3vp ^ |,DJ0  待续……51Testing软件测试网9f;X5e7Ea@#v:b


TAG:

 

评分:0

我来说两句

Open Toolbar