C++;启动一个脚本(bash、python…)并将stdin/stdout用于datatransfare[linux] < >我想从C++代码中调用python脚本。python脚本如下所示: hello.py #!/usr/bin/python import sys print "Hello!" Readin = sys.stdin.read() print Readin // maybe not all includes are necessary #include <iostream> #include <fstream> #include <string> #include <errno.h> #include <sys/stat.h> // mkdir #include <stdlib.h> // system() #include <unistd.h> // rmdir #include <cstring> // memset // wait: #include <sys/types.h> #include <sys/wait.h> using namespace std; int main() { char target[] = "./hello.py"; enum PIPE_FILE_DESCRIPTERS { READ_FD = 0, WRITE_FD = 1 }; enum CONSTANTS { BUFFER_SIZE = 100 }; int parentToChild[2]; int childToParent[2]; pid_t pid; string dataReadFromChild; char buffer[BUFFER_SIZE + 1]; memset(buffer,0x00,BUFFER_SIZE + 1); ssize_t readResult; int status; int retPipe1 = pipe(parentToChild); int retPipe2 = pipe(childToParent); switch (pid = fork()) { case -1: printf("Fork failed"); exit(-1); case 0: /* Child will start scripts*/ { // Bending stdin/out to the pipes? int retdup21 = dup2(parentToChild[READ_FD], STDIN_FILENO); int retdup22 = dup2(childToParent[WRITE_FD], STDOUT_FILENO); int retdup23 = dup2(childToParent[WRITE_FD], STDERR_FILENO); // Close in this Process the other sides of the pipe int retclose1 = close(parentToChild[WRITE_FD]); int retclose2 = close(childToParent[READ_FD]); int retexe = execlp( target ," "); // warning not enough variable arguments to fit a sentinel [-Wformat=] printf("This line should never be reached!!!"); // why? what happens if execlp finishes? exit(-1); break; // to make the compiler happy =) } default: /* Parent */ cout << "Child " << pid << " process running..." << endl; // close the other ends of the pipe from the other process. int retdup21 = close(parentToChild[READ_FD]); int retdup22 = close(childToParent[WRITE_FD]); // readtry while (true) { switch (readResult = read(childToParent[READ_FD], buffer, 1)) // execution does not return from this function. { case 0: /* End-of-File, or non-blocking read. */ { cout << "End of file reached..." << endl << "Data received was (" << dataReadFromChild.size() << "):" << endl << dataReadFromChild << endl; cout << "starting writing" << endl; char bufferW[] = "{\"AElement\":\"Something\"}\0"; int writeResult = write(parentToChild[WRITE_FD],bufferW,sizeof(bufferW)); int saveerrno = errno; if( -1 == writeResult) { cout << "errno while writing: " << errno << std::endl; if ( 9 == saveerrno ) cout << "Errno Bad File descriptor" << endl; } cout << "Write Result: " << writeResult << std::endl; int retWait = waitpid(pid, &status, 0); cout << endl << "Child exit staus is: " << WEXITSTATUS(status) << endl << endl; exit(0); } case -1: { if ((errno == EINTR) || (errno == EAGAIN)) { errno = 0; break; } else { printf("read() failed"); exit(-1); } } default: dataReadFromChild.append(buffer, readResult); printf("%s",buffer); memset(buffer,0x00,BUFFER_SIZE + 1); break; } } /* while ( true ) */ } /* switch ( pid = fork() )*/ } < > C++代码来自堆栈溢出的另一个问题。工作原理:
创建一对管道C++;启动一个脚本(bash、python…)并将stdin/stdout用于datatransfare[linux] < >我想从C++代码中调用python脚本。python脚本如下所示: hello.py #!/usr/bin/python import sys print "Hello!" Readin = sys.stdin.read() print Readin // maybe not all includes are necessary #include <iostream> #include <fstream> #include <string> #include <errno.h> #include <sys/stat.h> // mkdir #include <stdlib.h> // system() #include <unistd.h> // rmdir #include <cstring> // memset // wait: #include <sys/types.h> #include <sys/wait.h> using namespace std; int main() { char target[] = "./hello.py"; enum PIPE_FILE_DESCRIPTERS { READ_FD = 0, WRITE_FD = 1 }; enum CONSTANTS { BUFFER_SIZE = 100 }; int parentToChild[2]; int childToParent[2]; pid_t pid; string dataReadFromChild; char buffer[BUFFER_SIZE + 1]; memset(buffer,0x00,BUFFER_SIZE + 1); ssize_t readResult; int status; int retPipe1 = pipe(parentToChild); int retPipe2 = pipe(childToParent); switch (pid = fork()) { case -1: printf("Fork failed"); exit(-1); case 0: /* Child will start scripts*/ { // Bending stdin/out to the pipes? int retdup21 = dup2(parentToChild[READ_FD], STDIN_FILENO); int retdup22 = dup2(childToParent[WRITE_FD], STDOUT_FILENO); int retdup23 = dup2(childToParent[WRITE_FD], STDERR_FILENO); // Close in this Process the other sides of the pipe int retclose1 = close(parentToChild[WRITE_FD]); int retclose2 = close(childToParent[READ_FD]); int retexe = execlp( target ," "); // warning not enough variable arguments to fit a sentinel [-Wformat=] printf("This line should never be reached!!!"); // why? what happens if execlp finishes? exit(-1); break; // to make the compiler happy =) } default: /* Parent */ cout << "Child " << pid << " process running..." << endl; // close the other ends of the pipe from the other process. int retdup21 = close(parentToChild[READ_FD]); int retdup22 = close(childToParent[WRITE_FD]); // readtry while (true) { switch (readResult = read(childToParent[READ_FD], buffer, 1)) // execution does not return from this function. { case 0: /* End-of-File, or non-blocking read. */ { cout << "End of file reached..." << endl << "Data received was (" << dataReadFromChild.size() << "):" << endl << dataReadFromChild << endl; cout << "starting writing" << endl; char bufferW[] = "{\"AElement\":\"Something\"}\0"; int writeResult = write(parentToChild[WRITE_FD],bufferW,sizeof(bufferW)); int saveerrno = errno; if( -1 == writeResult) { cout << "errno while writing: " << errno << std::endl; if ( 9 == saveerrno ) cout << "Errno Bad File descriptor" << endl; } cout << "Write Result: " << writeResult << std::endl; int retWait = waitpid(pid, &status, 0); cout << endl << "Child exit staus is: " << WEXITSTATUS(status) << endl << endl; exit(0); } case -1: { if ((errno == EINTR) || (errno == EAGAIN)) { errno = 0; break; } else { printf("read() failed"); exit(-1); } } default: dataReadFromChild.append(buffer, readResult); printf("%s",buffer); memset(buffer,0x00,BUFFER_SIZE + 1); break; } } /* while ( true ) */ } /* switch ( pid = fork() )*/ } < > C++代码来自堆栈溢出的另一个问题。工作原理:,python,c++,linux,stdout,stdin,Python,C++,Linux,Stdout,Stdin,创建一对管道 使用fork()创建子进程 child正在将管道弯曲到标准DIN/stdout。关闭另一端 然后开始写剧本 父亲正在监听管道read(),接收输入。之后呢,, 发送消息write() 当输入开关(readResult=read(childToPa…)时,程序不会从行返回 我也不知道这个写作部分是否发挥了作用。这是一个很有希望的想法,还是有其他工作的可能性? 谢谢 它看起来像: hello.py #!/usr/bin/python import sys
fork()
创建子进程read()
,接收输入。之后呢,,
发送消息write()
开关(readResult=read(childToPa…
)时,程序不会从行返回
我也不知道这个写作部分是否发挥了作用。这是一个很有希望的想法,还是有其他工作的可能性?
谢谢
它看起来像:
hello.py
#!/usr/bin/python
import sys
print "Hello!"
Readin = sys.stdin.read()
print Readin
// maybe not all includes are necessary
#include <iostream>
#include <fstream>
#include <string>
#include <errno.h>
#include <sys/stat.h> // mkdir
#include <stdlib.h> // system()
#include <unistd.h> // rmdir
#include <cstring> // memset
// wait:
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main() {
char target[] = "./hello.py";
enum PIPE_FILE_DESCRIPTERS {
READ_FD = 0, WRITE_FD = 1
};
enum CONSTANTS {
BUFFER_SIZE = 100
};
int parentToChild[2];
int childToParent[2];
pid_t pid;
string dataReadFromChild;
char buffer[BUFFER_SIZE + 1];
memset(buffer,0x00,BUFFER_SIZE + 1);
ssize_t readResult;
int status;
int retPipe1 = pipe(parentToChild);
int retPipe2 = pipe(childToParent);
switch (pid = fork()) {
case -1:
printf("Fork failed");
exit(-1);
case 0: /* Child will start scripts*/
{
// Bending stdin/out to the pipes?
int retdup21 = dup2(parentToChild[READ_FD], STDIN_FILENO);
int retdup22 = dup2(childToParent[WRITE_FD], STDOUT_FILENO);
int retdup23 = dup2(childToParent[WRITE_FD], STDERR_FILENO);
// Close in this Process the other sides of the pipe
int retclose1 = close(parentToChild[WRITE_FD]);
int retclose2 = close(childToParent[READ_FD]);
int retexe = execlp( target ," "); // warning not enough variable arguments to fit a sentinel [-Wformat=]
printf("This line should never be reached!!!"); // why? what happens if execlp finishes?
exit(-1);
break; // to make the compiler happy =)
}
default: /* Parent */
cout << "Child " << pid << " process running..." << endl;
// close the other ends of the pipe from the other process.
int retdup21 = close(parentToChild[READ_FD]);
int retdup22 = close(childToParent[WRITE_FD]);
// readtry
while (true) {
switch (readResult = read(childToParent[READ_FD], buffer, 1)) // execution does not return from this function.
{
case 0: /* End-of-File, or non-blocking read. */
{
cout << "End of file reached..." << endl << "Data received was (" << dataReadFromChild.size() << "):" << endl
<< dataReadFromChild << endl;
cout << "starting writing" << endl;
char bufferW[] = "{\"AElement\":\"Something\"}\0";
int writeResult = write(parentToChild[WRITE_FD],bufferW,sizeof(bufferW));
int saveerrno = errno;
if( -1 == writeResult)
{
cout << "errno while writing: " << errno << std::endl;
if ( 9 == saveerrno )
cout << "Errno Bad File descriptor" << endl;
}
cout << "Write Result: " << writeResult << std::endl;
int retWait = waitpid(pid, &status, 0);
cout << endl << "Child exit staus is: " << WEXITSTATUS(status) << endl << endl;
exit(0);
}
case -1:
{
if ((errno == EINTR) || (errno == EAGAIN)) {
errno = 0;
break;
} else {
printf("read() failed");
exit(-1);
}
}
default:
dataReadFromChild.append(buffer, readResult);
printf("%s",buffer);
memset(buffer,0x00,BUFFER_SIZE + 1);
break;
}
} /* while ( true ) */
} /* switch ( pid = fork() )*/
}
//可能并非所有包含都是必需的
#包括
#包括
#包括
#包括
#包括//mkdir
#包括//系统()
#包括//rmdir
#include//memset
//等等:
#包括
#包括
使用名称空间std;
int main(){
char target[]=“/hello.py”;
枚举管道\文件\描述符{
读取\u FD=0,写入\u FD=1
};
枚举常数{
缓冲区大小=100
};
int parentToChild[2];
int childToParent[2];
pid_t pid;
字符串dataReadFromChild;
字符缓冲区[缓冲区大小+1];
memset(缓冲区,0x00,缓冲区大小+1);
ssize_t readResult;
智力状态;
int retPipe1=管道(parentToChild);
int-retPipe2=管道(childToParent);
开关(pid=fork()){
案例1:
printf(“Fork失败”);
出口(-1);
案例0:/*子级将启动脚本*/
{
//将标准件弯曲到管道上?
int retdup21=dup2(parentToChild[READ\u FD],STDIN\u FILENO);
int retdup22=dup2(childToParent[WRITE\u FD],STDOUT\u FILENO);
int retdup23=dup2(childToParent[WRITE_FD],STDERR_FILENO);
//在这一过程中,关闭管道的另一侧
int retclose1=close(parentToChild[WRITE_FD]);
int retclose2=关闭(childToParent[READ_FD]);
int-retexe=execlp(target,“”;//警告变量参数不足,无法容纳sentinel[-Wformat=]
printf(“永远不能到达此行!!!”;//为什么?如果execlp完成会发生什么?
出口(-1);
break;//使编译器满意=)
}
默认值:/*父级*/
cout您的问题是缓冲输出、未关闭的文件描述符以及使用EOF发出传输部分结束的信号。前两个问题可以解决,但后一个问题需要不同的方法。稍后将详细介绍
逐步:
Python正在使用缓冲I/O,因此您可能希望通过在第一个print语句后添加一行sys.stdout.flush()
,强制Python刷新输出。现在“Hello!\n”
是逐字符读取的
但是接下来的代码>读取< /Cube块,直到新的字符到达或管道关闭。Python脚本的STDUT仍然是打开的,C++程序在等待某些东西到达,但是Python脚本本身也在等待一些输入。经典死锁。
您可以放弃python脚本中的最后一次打印,并尝试关闭其标准输出。由于read
阻塞,直到引用管道写入端的所有文件描述符都关闭为止,因此必须在刷新后添加os.close(sys.STDOUT.fileno())
和os.close(sys.STDOUT.fileno())
但仍然有有效的文件描述符引用该管道的写入部分。请记住C++源中的<代码> DUP2<代码>?在这三个代码> DUP2< /代码>行之后,仍然存在<代码> PARTROTBOD[读入FD] <代码>和<代码>子PotoPrut[Read EfFD]
引用脚本STDIN和STDOUT。因此我们必须关闭它们。添加close(parentToChild[READ_FD])
和close(childToParent[WRITE_FD]);
就在dup2
s之后。现在READ
在Python脚本关闭STDOUT和STDERR时返回0
接下来,父对象发送“{\'aeelement\”:\'Something\“}\0”
,并到达waitpid
,当子对象退出时返回。但是子对象仍在从STDIN读取。因此,您必须在waitpid
之前添加关闭(parentToChild[WRITE\u FD]);
现在来看概念部分:在它返回0
(管道关闭)之前,您不能read()
,然后继续从该关闭的管道读取。您的选择:
- 阅读一次,直到管道关闭。不可能出现第二条消息
- 提前或通过解释接收到的字节,知道要读取多少
- 监控两个管道,例如使用,并动态决定是否要读取或写入
顺便说一句:execlp
的参数是const char*file,const char*arg,…
,其中arg,…
是通常的char*args[]
从arg[0]
(!)开始,以空指针结束。请将该行更改为int-retexe=execlp(target,target,(char*)null);
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
const char*target=“/hello.py”;
枚举管道\文件\描述符{
读取\u FD=0,写入\u FD=1
};
/*制造管道*/
int parentToChild[2];/*父到子管道*/
if(管道(父对象子对象)<0)
{
佩罗(“不会制造管道”);
出口(1);
}
int childToParent[2];/*子管道到父管道*/
if(管道(儿童家长)<0)
{
佩罗(“不会制造管道”);
出口(1);
}
/*创建要运行的子命令*/
pid_t pid=fork();
开关(pid)
{
案例1:
佩罗(“不会叉子”);
出口(1);
案例0:/*儿童*/
关闭(parentToChild[WRITE_FD]);