`
tomhibolu
  • 浏览: 1430934 次
文章分类
社区版块
存档分类
最新评论

从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参数对应的):

  • PCTSTRpszApplicationName

按照Windows核心编程一书中说法,99%的情况下,我们都是直接传递一个NULL给它。它存在的原本目的是为了支持Windows的posix子系统。

如果指定了这个参数:程序名后缀必须指定;而且不在当前工作路径下的话,必须指定全路径。

注:Qt在WindowCE下的实现在使用这个参数。

  • PTSTRpszCommandLine

如果前一个参数为NULL,则该字符串参数中第一个空格(被双引号括住的不算)前的内容则为应该程序的程序名。

如果程序名不包含路径,则按照下列顺序查找:

  • 当前进程的程序文件的所在目录
  • 当前进程的工作目录
  • Windows的system32目录
  • Windows目录
  • 环境变量PATH中的目录

注意,这是一个字符串。而在unix下,是一个字符串的列表。所在当参数中包含空格等东西时,在Windows下总是需要特殊处理。

  • PVOIDpvEnvironment

环境变量

  • PCTSTRpszCurDir

指定工作目录,这个前面没提到。因为在unix下,分成fork()/execve()两个阶段,在fork()之后直接调用chdir设置进程的工作目录即可。

同样,看一下 QProcess::startDetached()的情况:

BOOLbInheritHandles

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 消息


分享到:
评论

相关推荐

    【QT】通过QProcess实现一个命令行

    总的来说,通过QProcess实现一个命令行界面,不仅涉及到QProcess类的使用,还包括了命令解析、输入输出处理、用户交互等多个方面的编程技术。这是一个很好的学习实践,可以让你深入理解QT框架的高级特性及其在实际...

    Ping with new QProcess

    在本文中,我们将深入探讨如何在QT5框架下利用QProcess类来实现ping命令的功能,同时解决中文显示异常的问题。QProcess是QT库中的一个关键组件,它允许我们与操作系统进行交互,执行外部应用程序并捕获其输出。在这...

    qt使用QProcess实现父子进程通信,适用linux平台

    在IT领域,尤其是在软件开发中,进程间的通信(IPC,Inter-Process Communication)是一个至关重要的概念,特别是在多任务操作系统如Linux上。...因此,理解并掌握这一技术对于Qt开发者来说是至关重要的。

    qt QProcess 类调用 mplayer

    本示例中,我们将关注的是如何在Qt环境中利用QProcess类来调用mplayer,一个流行的多媒体播放器,特别是在Linux系统上。首先,让我们深入理解相关的关键概念。 **Qt框架**:Qt是一个跨平台的C++图形用户界面库,它...

    Qprocess实例

    总的来说,`QProcess实例`是QT中处理外部进程的关键工具,通过理解和运用它的特性,开发者可以轻松地在QT应用中集成外部程序,如打开Word文档,同时处理各种边缘情况,如汉字和空格,以及确保资源的妥善管理。

    QT+QProcess+进程双向通信

    QT+QProcess+进程双向通信

    C++ QT调用外部程序(QProcess)

    `QProcess`类是Qt中用于执行外部应用程序的关键工具,它允许开发者在应用程序中启动、监控以及通信与外部进程。这篇博客文章将深入探讨如何使用`QProcess`在C++中调用外部程序,以及相关的细节和注意事项。 首先,`...

    QProcess进程间通信.rar

    总结来说,"QProcess进程间通信.rar"的示例展示了如何利用Qt的QProcess类在Windows环境下实现父子进程的双向通信,这对于开发跨进程协作的应用程序至关重要。通过理解和实践这样的例子,开发者可以更深入地掌握进程...

    QProcess资料大全

    总的来说,QProcess是QT框架中处理外部进程的强大工具,提供了丰富的功能和良好的可扩展性,使得与外部程序的交互变得简单且高效。无论是简单的命令执行还是复杂的进程管理,QProcess都能够满足需求。

    QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中.7z

    总的来说,通过QProcess和特定的窗口嵌入技术,我们可以实现QT应用程序调用外部程序并将其界面无缝集成到主窗口中。这种方式为开发者提供了丰富的扩展性,能够利用已有的工具和应用增强QT界面的功能。在实践中,你...

    使用QProcess启动并嵌入带界面应用程序

    在做系统集成框架软件时,经常遇到需要将已有程序的界面嵌入到统一框架软件的情形,该示例程序演示了在Qt5平台下面,使用QProcess启动并嵌入带界面应用程序的方法。该方法在Windows、Linux等操作系统下测试通过,...

    QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中

    总结来说,QT通过QProcess调用外部可执行程序并嵌入到主窗口中的步骤包括: 1. 创建QProcess对象。 2. 启动外部程序并设置工作目录。 3. 连接QProcess的信号到相应的槽,以便处理输出。 4. 在槽函数中读取并显示输出...

    Qt案例之利用QProcess类实现启动进程的功能进阶(以dos命令dir为例)

    Qt案例之利用QProcess类实现启动进程的功能进阶(以dos命令dir为例),详细内容可参考文章:https://blog.csdn.net/didi_ya/article/details/123180765

    qprocess.exe

    qprocess

    Qt实战案例之利用QProcess获取计算机硬件信息

    首先,我们从`widget.cpp`和`main.cpp`这两个源代码文件开始。在`widget.cpp`中,通常会定义一个自定义的Widget类,扩展自QWidget,这个类包含了获取硬件信息的具体逻辑。`main.cpp`是应用程序的入口点,创建并显示...

    Qt实战案例之利用QProcess实现应用程序重启功能.zip

    Qt实战案例之利用QProcess实现应用程序重启功能.zip,可参考文章:https://wendy.blog.csdn.net/article/details/126087475

    QProcess.zip

    总的来说,QProcess是Qt中处理进程操作的强大工具,它简化了与外部进程的交互,使得在C++ Qt应用中调用系统命令和管理进程变得更加便捷。通过熟练掌握QProcess的使用,开发者能够更好地实现跨进程通信,提高应用的...

    QProgress_Qprocess_Qprogress_QT_

    在Qt框架中,`QProcess`和`QProgressDialog`是两个非常重要的类,它们分别用于执行外部进程和显示进度条信息。在这个项目中,我们看到标题提到“QProgress_Qprocess_Qprogress_QT”,这暗示了它涉及到使用Qt来管理...

    Qt6案例之利用QProcess获取计算机硬件信息

    Qt6案例之利用QProcess获取计算机硬件信息,介绍利用QProcess获取计算机的CPU、主板、硬盘等电脑相关硬件信息。windows提供了“wmic”(Windows Management Instrumentation,Windows管理工具),提供了从命令行接口...

Global site tag (gtag.js) - Google Analytics