使用 C++ 读取进程本身的标准输出
read stdout of a process in itself using c++
考虑我们有 some_function
并将结果打印到 stdout
而不是返回 it.Changing 它的定义超出了我们的范围并且没有其他选择。我们可以选择从 stdout
读取它。所以问题。
如何读取 C++ 程序本身的标准输出。
有可能获得 pid
我搜索了我们是否可以获得相同程序的 fd
但我找不到任何东西。
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
void some_function(){
std::cout<<"Hello World";
}
int main(){
int pid = ::getpid();
string s = //What to write here.
cout<<"Printing";
some_function(); //This function prints "Hello World" to screen
cout<<s; //"PrintingHello World"
return 0;
}
如何将管道附加到同一进程,即而不是创建子进程。
有些人可能会想到创建子进程并在其中调用 some_function
,以便能够在父进程中读取其 stdout
,但是不,some_function
取决于调用的进程它因此我们想称它为进程本身而不是创建子进程。
How to read stdout of C++ program in itself?
这样做的理由很少,这通常(但不总是)是设计错误。
注意一件重要的事情(至少在 single-threaded 程序中)。如果您的程序既从其 "stdout" 中读取又(像往常一样)在其中写入,它可能会陷入死锁:无法读取,因此无法到达任何输出例程,(或无法写入,因为管道已满).
所以一个程序同时读取和写入相同的东西(实际上,相同的两侧pipe(7)) should use some multiplexing call like poll(2). See also this。
一旦你明白了这一点,你就会有一些 event loop. And before that, you'll make a pipe(7) using pipe(2) (and dup2(2)).
然而,在某些 signal(7) handling (see signal-safety(7)). That trick is even recommended in Qt Unix signal handling.
中,pipe to self 是一件好事
阅读有关 Unix 系统编程的更多信息,例如ALP or some newer book. Read also intro(2) & syscalls(2).
I have looked for pipe and it requires fd
错了。仔细阅读pipe(2); on success it fills an array of two file descriptors. Of course it could fail (see errno(3) & perror(3) & strerror(3))
也许你只需要 popen(3). Or std::ostringstream
. Or open_memstream(3).
Consider we have some_function and it prints result to stdout instead returning it. Changing it's definition is out of our scope and there's no alternative to it
如果 some_function
是您的代码,或者是一些 free software,您可以并且可能应该改进它以在某处给出结果....
这并不难,但在我看来这很麻烦,而且它不适用于多线程程序:
// make a temp file to store the function's stdout
int newStdOut = mkstemp( "/tmp/stdout.XXXXXXX" );
// save the original stdout
int tmpStdOut = dup( STDOUT_FILENO );
// clear stdout
fflush( stdout );
// now point the stdout file descriptor to the file
dup2( newStdOut, STDOUT_FILENO );
// call the function we want to collect the stdout from
some_function();
// make sure stdout is empty
fflush( stdout );
// restore original stdout
dup2( tmpStdOut, STDOUT_FILENO );
// the tmp file now contains whatever some_function() wrote to stdout
错误检查、正确 headers、将 C stdout
与 C++ cout
同步以及读取和清理临时文件留作练习...;-)
请注意,您不能安全地使用管道 - 函数可以写入足够多的内容来填满管道,并且您不能从管道中读取,因为您已经调用了函数。
考虑我们有 some_function
并将结果打印到 stdout
而不是返回 it.Changing 它的定义超出了我们的范围并且没有其他选择。我们可以选择从 stdout
读取它。所以问题。
如何读取 C++ 程序本身的标准输出。
有可能获得 pid
我搜索了我们是否可以获得相同程序的 fd
但我找不到任何东西。
#include <unistd.h>
#include <sys/types.h>
#include <iostream>
void some_function(){
std::cout<<"Hello World";
}
int main(){
int pid = ::getpid();
string s = //What to write here.
cout<<"Printing";
some_function(); //This function prints "Hello World" to screen
cout<<s; //"PrintingHello World"
return 0;
}
如何将管道附加到同一进程,即而不是创建子进程。
有些人可能会想到创建子进程并在其中调用 some_function
,以便能够在父进程中读取其 stdout
,但是不,some_function
取决于调用的进程它因此我们想称它为进程本身而不是创建子进程。
How to read stdout of C++ program in itself?
这样做的理由很少,这通常(但不总是)是设计错误。
注意一件重要的事情(至少在 single-threaded 程序中)。如果您的程序既从其 "stdout" 中读取又(像往常一样)在其中写入,它可能会陷入死锁:无法读取,因此无法到达任何输出例程,(或无法写入,因为管道已满).
所以一个程序同时读取和写入相同的东西(实际上,相同的两侧pipe(7)) should use some multiplexing call like poll(2). See also this。
一旦你明白了这一点,你就会有一些 event loop. And before that, you'll make a pipe(7) using pipe(2) (and dup2(2)).
然而,在某些 signal(7) handling (see signal-safety(7)). That trick is even recommended in Qt Unix signal handling.
中,pipe to self 是一件好事阅读有关 Unix 系统编程的更多信息,例如ALP or some newer book. Read also intro(2) & syscalls(2).
I have looked for pipe and it requires fd
错了。仔细阅读pipe(2); on success it fills an array of two file descriptors. Of course it could fail (see errno(3) & perror(3) & strerror(3))
也许你只需要 popen(3). Or std::ostringstream
. Or open_memstream(3).
Consider we have some_function and it prints result to stdout instead returning it. Changing it's definition is out of our scope and there's no alternative to it
如果 some_function
是您的代码,或者是一些 free software,您可以并且可能应该改进它以在某处给出结果....
这并不难,但在我看来这很麻烦,而且它不适用于多线程程序:
// make a temp file to store the function's stdout
int newStdOut = mkstemp( "/tmp/stdout.XXXXXXX" );
// save the original stdout
int tmpStdOut = dup( STDOUT_FILENO );
// clear stdout
fflush( stdout );
// now point the stdout file descriptor to the file
dup2( newStdOut, STDOUT_FILENO );
// call the function we want to collect the stdout from
some_function();
// make sure stdout is empty
fflush( stdout );
// restore original stdout
dup2( tmpStdOut, STDOUT_FILENO );
// the tmp file now contains whatever some_function() wrote to stdout
错误检查、正确 headers、将 C stdout
与 C++ cout
同步以及读取和清理临时文件留作练习...;-)
请注意,您不能安全地使用管道 - 函数可以写入足够多的内容来填满管道,并且您不能从管道中读取,因为您已经调用了函数。