阻止版本的execvp(Windows)
此问题与 system()的非阻止版本完全相反
我想用另一个过程代替当前过程(而不创建另一个过程).
I want to substitute the current process by another one (not create another one).
我想启动(例如)notepad
,但是以一种阻塞的方式(我不想在关闭notepad
之前得到提示.
I want to start (for instance) notepad
, but in a blocking way (I don't want to get the prompt until notepad
is closed.
在Windows shell中,我只是做
In the Windows shell I just do
cmd /c notepad
((notepad
如果不带cmd /c
前缀则自动与提示分离)
(notepad
auto-detachs from prompt if not prefixed by cmd /c
)
在C语言中,我只是使用system
In C, using system
I just do
system("notepad");
但这是幕后花絮.我想用notepad
替换当前进程,并且希望它被阻止.
But this is forking behind the scenes. I want to replace the current process by notepad
, and I want it to be blocking.
我尝试过:
#include <stdio.h>
#include <unistd.h>
int main(int argc,char **argv)
{
char * const args[] = {"cmd","/c","notepad",NULL};
execvp(args[0],args);
}
notepad
运行,但控制台立即返回提示.(非阻塞).我希望它阻止,并且我不想使用fork
,因为它会创建另一个进程:我想替换当前进程.
notepad
runs, but the console returns to the prompt immediately.(non-blocking). I want it to block, and I don't want to use fork
as it would create another process: I want to replace the current process.
(我尝试过使用自定义阻止可执行文件,但它也不会阻止.因此cmd /c notepad
示例与其他任何示例一样好)
(I have tried with a custom blocking executable, and it doesn't block either. So cmd /c notepad
example is as good as any other one)
因此,如果我运行此可执行文件,那么我只是从父进程中构建的:
So, If I run this executable I just built from a parent process:
- 在
notepad
进程退出之前,我不希望该进程返回到父进程. - 我希望能够从命令中获取输出(在这种情况下,
notepad
不是一个很好的例子) - 我不想创建额外的流程(这是大型多处理应用程序的一部分,我们无力创建2个流程,每次运行都需要保留1个流程)
- I don't want the process to return to the parent process until the
notepad
process exits - I want to be able to get output from the command (
notepad
isn't a good example in that case) - I don't want to create an extra process (this is part of a massive multiprocessing application, we can't afford to create 2 processes, we need to keep 1 process for each run)
有可能吗?
目前尚不清楚您想要什么-如果当前子进程由子可执行文件替换了 ,则当前进程将无法等待子进程通过execv*()
函数.
It's not exactly clear what you want - the current process can't wait on the child process if it's replaced by the child executable via an execv*()
function.
A possible system()
replacement - on Windows - is _spawnvp()
:
intptr_t _spawnvp(
int mode,
const char *cmdname,
const char *const *argv
);
只需使用
int rc = _spawnvp( _P_WAIT, command, args );
(我怀疑此确切功能在POSIX系统上不可用的原因是,它很容易通过fork()
,exec*()
和wait()
的变体在POSIX上实现.与Windows等效的功能要多一些复杂.)
(I suspect the reason this exact functionality isn't available on POSIX systems is that it's easily implemented on POSIX via fork()
, exec*()
, and a variation of wait()
. Windows equivalents of those are a bit more complex.)
使用Windows _spawn*()
函数时要注意的一件事是文件名中带有空格.我在通过此函数传递此类文件名时遇到了一些实际问题,不得不对其进行引用.
One thing to be careful of when using Windows _spawn*()
functions is filenames with spaces in them. I've had some real issues passing such filenames via this function and had to quote them.