在C#中的Windows上,我可以通过调用Process.Start()从代码中启动外部程序,这将启动进程并返回其ID。这很重要,因为我没有派生自己的进程,稍后我可能不得不杀死该进程。我看过exec()、fork()和其他很多在Linux下用C++编写的程序,但它们都没有做完全相同的事情。例如,system()在程序运行时阻塞,fork()复制我的整个进程,这样我就可以运行另一个任务。有人能告诉我等价物是什么吗?
Process.Start()
exec()
fork()
system()
k4aesqcs1#
在Linux上启动一个新进程的方法是使用fork和exec。你可以把它 Package 在你自己的System类中,这个类保存了PID并提供了杀死进程的方法。这样一个类的例子是Qt库中的QProcess。注意:还有posix_spawn()和(特定于Linux的)clone()函数。
fork
exec
System
QProcess
mkh04yzy2#
这是Windows和Linux的区别(以及任何其他类Unix系统)。在类Unix系统中,新进程总是使用fork() + exec()启动。像system()这样的高级C库API在后台使用fork() + exec()系统调用,因为绝对没有其他方法。但是Windows总是从头开始创建新进程。但是你不应该因为fork()创建当前进程的副本。事实上,它以一种非常特定的方式执行,因此在写入内存之前几乎没有复制任何内容。即使在这种情况下,也只复制修改过的内存页。否则,在Unix/Linux上创建新进程将过于昂贵(例如,假设一个消耗4GB内存的进程想要执行一些shell命令)。事实上,exec()执行CreateProcess()在Windows上执行的工作-将新的可执行映像分配给进程,重新配置堆和堆栈。
fork() + exec()
CreateProcess()
jk9hmnmh3#
感谢@user4581301上面的评论。posix_spawn()是我要找的。下面是我最终使用的代码。
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 器。
posix_spawn
3条答案
按热度按时间k4aesqcs1#
在Linux上启动一个新进程的方法是使用
fork
和exec
。你可以把它 Package 在你自己的System
类中,这个类保存了PID并提供了杀死进程的方法。这样一个类的例子是Qt库中的QProcess
。注意:还有posix_spawn()和(特定于Linux的)clone()函数。
mkh04yzy2#
这是Windows和Linux的区别(以及任何其他类Unix系统)。在类Unix系统中,新进程总是使用
fork() + exec()
启动。像system()
这样的高级C库API在后台使用fork() + exec()
系统调用,因为绝对没有其他方法。但是Windows总是从头开始创建新进程。但是你不应该因为fork()
创建当前进程的副本。事实上,它以一种非常特定的方式执行,因此在写入内存之前几乎没有复制任何内容。即使在这种情况下,也只复制修改过的内存页。否则,在Unix/Linux上创建新进程将过于昂贵(例如,假设一个消耗4GB内存的进程想要执行一些shell命令)。事实上,exec()
执行CreateProcess()
在Windows上执行的工作-将新的可执行映像分配给进程,重新配置堆和堆栈。jk9hmnmh3#
感谢@user4581301上面的评论。
posix_spawn()
是我要找的。下面是我最终使用的代码。
字符串
这是可行的,我还没有尝试切换到使用
posix_spawn
,但正如讨论的那样,这只是一个 Package 器。