Linux中与Process.Start()等效的方法

0qx6xfy6  于 2023-11-17  发布在  Linux
关注(0)|答案(3)|浏览(181)

在C#中的Windows上,我可以通过调用Process.Start()从代码中启动外部程序,这将启动进程并返回其ID。这很重要,因为我没有派生自己的进程,稍后我可能不得不杀死该进程。
我看过exec()fork()和其他很多在Linux下用C++编写的程序,但它们都没有做完全相同的事情。例如,system()在程序运行时阻塞,fork()复制我的整个进程,这样我就可以运行另一个任务。
有人能告诉我等价物是什么吗?

k4aesqcs

k4aesqcs1#

在Linux上启动一个新进程的方法是使用forkexec。你可以把它 Package 在你自己的System类中,这个类保存了PID并提供了杀死进程的方法。这样一个类的例子是Qt库中的QProcess
注意:还有posix_spawn()和(特定于Linux的)clone()函数。

mkh04yzy

mkh04yzy2#

这是Windows和Linux的区别(以及任何其他类Unix系统)。在类Unix系统中,新进程总是使用fork() + exec()启动。像system()这样的高级C库API在后台使用fork() + exec()系统调用,因为绝对没有其他方法。但是Windows总是从头开始创建新进程。但是你不应该因为fork()创建当前进程的副本。事实上,它以一种非常特定的方式执行,因此在写入内存之前几乎没有复制任何内容。即使在这种情况下,也只复制修改过的内存页。否则,在Unix/Linux上创建新进程将过于昂贵(例如,假设一个消耗4GB内存的进程想要执行一些shell命令)。事实上,exec()执行CreateProcess()在Windows上执行的工作-将新的可执行映像分配给进程,重新配置堆和堆栈。

jk9hmnmh

jk9hmnmh3#

感谢@user4581301上面的评论。posix_spawn()是我要找的。
下面是我最终使用的代码。

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

class ProcessCancelHelper {
 private:
  pid_t process_id_;

 public:
  ProcessCancelHelper()
  : process_id_(0) {}

  int StartProcess(const char* command_buffer) {
    const char* command_argv[4];
    command_argv[0] = "sh";
    command_argv[1] = "-c";
    command_argv[2] = command_buffer;
    command_argv[3] = nullptr;

    process_id_ = fork();
    if (process_id_ == -1) return -1;
    if (process_id_ == 0) {
      execvp(command_argv[0], const_cast<char* const*>(command_argv));
      assert(false && "execvp did not work");
      exit(-1);
    }

    int wait_status;
    if (waitpid(process_id_, &wait_status, 0))
    {
      process_id_ = 0;
      if (WIFEXITED(wait_status)) return (WEXITSTATUS(wait_status));
      return -1;
    }

    process_id_ = 0;
    return -1;
  }

  bool CancelProcess() {
    return (process_id_ != 0 && kill(process_id_, SIGKILL) == 0);
  }
}

字符串
这是可行的,我还没有尝试切换到使用posix_spawn,但正如讨论的那样,这只是一个 Package 器。

相关问题