Linux 创建进程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5883462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linux CreateProcess?
提问by Amir Saniyan
I developing on the Linux platform.
我在Linux平台上开发。
I want to create a new proccess in my library without replacing the current executing image.
我想在我的库中创建一个新的进程而不替换当前正在执行的图像。
Because I am developing a library, I don't have a main function.
因为我正在开发一个库,所以我没有一个 main 函数。
And I want to continue the new process after the invoker application closes (Just like CreateProcess
Windows API).
我想在调用程序关闭后继续新进程(就像CreateProcess
Windows API 一样)。
Is it possible in Linux or not?
在 Linux 中是否可能?
something like this function:
像这样的功能:
void Linux_CreateProcess(const char* app_name)
{
// Executing app_name.
// ???????? what is the code ??????
// app_name is running and never close if current application close.
return;
}
Note:
笔记:
system()
blocks the current process, it is not good. I want to continue the current process.exec()
family replace the current executing image, it is not good.popen()
closes the new process if the current process closed.
system()
阻塞当前进程,不好。我想继续当前的过程。exec()
family 替换当前的执行镜像,不好。popen()
如果当前进程关闭,则关闭新进程。
采纳答案by davmac
fork()
and then exec()
is the standard solution.
fork()
然后exec()
是标准溶液。
Use fork()
(or vfork()
) to launch a separate process, which will be a clone of the parent. In both the child and parent process, execution continues, but fork
returns a different value in either case allowing you to differentiate. You can then use exec()
from within the child process.
使用fork()
(或vfork()
) 启动一个单独的进程,它将是父进程的克隆。在子进程和父进程中,继续执行,但fork
在任何一种情况下都返回不同的值,允许您进行区分。然后您可以exec()
从子进程中使用。
Note, however - from one of my own blog posts (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
但是请注意 - 来自我自己的一篇博客文章(http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
There doesn't seem to be any simple standards-conformant way (or even a generally portable way) to execute another process in parallel and be certain that the exec() call was successful. The problem is, once you've fork()d and then successfully exec()d you can't communicate with the parent process to inform that the exec() was successful. If the exec() fails then you can communicate with the parent (via a signal for instance) but you can't inform of success – the only way the parent can be sure of exec() success is to wait() for the child process to finish (and check that there is no failure indication) and that of course is not a parallel execution.
似乎没有任何简单的符合标准的方式(甚至是通常可移植的方式)来并行执行另一个进程并确保 exec() 调用成功。问题是,一旦你 fork()d 然后成功 exec()d 你就不能与父进程通信以通知 exec() 成功。如果 exec() 失败,那么您可以与父级通信(例如通过信号),但您无法通知成功 - 父级可以确保 exec() 成功的唯一方法是 wait() 为子级进程完成(并检查是否有失败指示),当然这不是并行执行。
A potential solution to this problem, in case it is an issue in your case:
这个问题的潜在解决方案,如果它是你的问题:
[...] use pipe() to create a pipe, set the output end to be close-on-exec, then fork() (or vfork()), exec(), and write something (perhaps errno) to the pipe if the exec() fails (before calling _exit()). The parent process can read from the pipe and will get an immediate end-of-input if the exec() succeeds, or some data if the exec() failed.
[...] 使用 pipe() 创建管道,将输出端设置为 close-on-exec,然后 fork()(或 vfork())、exec(),并写入一些东西(可能是 errno)到如果 exec() 失败(在调用 _exit() 之前)。父进程可以从管道中读取,如果 exec() 成功,将立即获得输入结束,或者如果 exec() 失败,则获得一些数据。
(Note that this solution through is prone to causing priority inversion if the child process runs at a lower priority than the parent).
(请注意,如果子进程以低于父进程的优先级运行,则此解决方案容易导致优先级反转)。
There is also posix_spawn
as mentioned in other answers, but it is somewhat less portable (not available on older systems in particular) and doesn't resolve the above issue, since it is often implemented in terms of fork/exec anyway and can return success before the exec()
stage fails.
还有posix_spawn
其他答案中提到的,但它的便携性稍差(特别是在较旧的系统上不可用)并且不能解决上述问题,因为它通常是在 fork/exec 方面实现的,并且可以在之前返回成功该exec()
阶段将失败。
回答by Daniel A. White
I think fork
is what you are looking for.
我想fork
这就是你要找的。
回答by Alok Save
You should be using fork()
and then execvp()
.
你应该使用fork()
然后execvp()
。
fork()
function creates a new child process. In the parent process you receive the process ID of the child process. In Child process the process ID returned is 0, which tells us that the process is a child process.
fork()
函数创建一个新的子进程。在父进程中,您会收到子进程的进程 ID。Child进程中返回的进程ID为0,说明该进程是子进程。
execvp()
replaces the calling process image with a new process image. This has the effect of running a new program with the process ID of the calling process. Note that a new process is not started; the new process image simply overlays the original process image. The execvp function is most commonly used to overlay a process image that has been created by a call to the fork function.
execvp()
用新的过程映像替换调用过程映像。这具有使用调用进程的进程 ID 运行新程序的效果。注意没有启动一个新的进程;新的过程映像只是简单地覆盖原始过程映像。execvp 函数最常用于覆盖通过调用 fork 函数创建的进程映像。
回答by Alok Save
The classic way to do this is to use fork() to create a child process, and then use one of the exec() functions to replace the executing image of the child, leaving the parent untouched. Both process will then run in parallel.
执行此操作的经典方法是使用 fork() 创建子进程,然后使用 exec() 函数之一替换子进程的执行映像,而保持父进程不变。然后这两个过程将并行运行。
回答by Olwaro
Yes, fork() and exec..() is the correct solution. Look at this code if it can help you :
是的,fork() 和 exec..() 是正确的解决方案。如果它可以帮助您,请查看此代码:
switch( fork() )
{
case -1 : // Error
// Handle the error
break;
case 0 :
// Call one of the exec -- personally I prefer execlp
execlp("path/to/binary","binary name", arg1, arg2, .., NULL);
exit(42); // May never be returned
break;
default :
// Do what you want
break;
}
回答by Philipp
The fork
/exec
combination was already mentioned, but there is also the posix_spawn
family of functions that can be used as a replacement for fork
+ exec
and is a more direct equivalent to CreateProcess
. Here is an example for both possibilities:
将fork
/exec
组合已经提到,但也posix_spawn
可以用作替代的功能,家庭fork
+ exec
,是一个更直接等同于CreateProcess
。以下是两种可能性的示例:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
extern char **environ;
void test_fork_exec(void);
void test_posix_spawn(void);
int main(void) {
test_fork_exec();
test_posix_spawn();
return EXIT_SUCCESS;
}
void test_fork_exec(void) {
pid_t pid;
int status;
puts("Testing fork/exec");
fflush(NULL);
pid = fork();
switch (pid) {
case -1:
perror("fork");
break;
case 0:
execl("/bin/ls", "ls", (char *) 0);
perror("exec");
break;
default:
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
break;
}
}
void test_posix_spawn(void) {
pid_t pid;
char *argv[] = {"ls", (char *) 0};
int status;
puts("Testing posix_spawn");
fflush(NULL);
status = posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ);
if (status == 0) {
printf("Child id: %i\n", pid);
fflush(NULL);
if (waitpid(pid, &status, 0) != -1) {
printf("Child exited with status %i\n", status);
} else {
perror("waitpid");
}
} else {
printf("posix_spawn: %s\n", strerror(status));
}
}
回答by MarkR
I think posix_spawn does what you want. Internally it might do fork/exec, but maybe it also does some funky useful stuff.
我认为 posix_spawn 可以满足您的需求。在内部它可能会执行 fork/exec,但也许它也会做一些时髦的有用的东西。
回答by Ivan
You wrote:
你写了:
I want to create a new proccess in my library without replacing the current executing image. system() blocks the current process, it is not good. I want to continue current process.
我想在我的库中创建一个新的进程而不替换当前正在执行的图像。system() 阻塞当前进程,不好。我想继续当前的过程。
Just add an ampersand after the command call.
Example: system("/bin/my_prog_name &");
只需在命令调用后添加一个与号。例子:system("/bin/my_prog_name &");
Your process will not be blocked!
您的进程不会被阻止!