我尝试使用 Pipe() 在 Python 和 C 程序之间交换字符串,但什么也没得到。 之后我尝试使用 Pipe() 在两个 C 程序之间交换字符串,一切都很好。
Python父程序:
import os
def main():
r, w = os.pipe()
pid = os.fork()
if pid == 0:
os.close(r)
print('fd =', w)
name = '/home/subado/tmp/pipes/c' # compiled c.c
os.execl(name, name, str(w))
else:
os.close(w)
os.waitpid(-1, 0)
print('Parent receive: ', os.read(r, 10))
os.close(r)
if __name__ == "__main__":
main()
儿童抄送程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
exit(EXIT_FAILURE);
}
char buf[] = "1000 - 7?";
int fd = (int)strtol(argv[1], (char **)NULL, 10);
printf("fd = %d\n", fd);
ssize_t count = write(fd, buf, sizeof(buf));
if (count == -1) {
perror("write");
exit(EXIT_FAILURE);
} else {
printf("Child send: %s\n", buf);
}
close(fd);
exit(EXIT_SUCCESS);
}
Python父程序输出:
fd = 4
fd = 4
write: Bad file descriptor
Parent receive: b''
但是当我在 C 中编写相同的父程序时:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void) {
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
pid_t cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) {
close(pipefd[0]);
printf("fd = %d\n", pipefd[1]);
const char *child = "/home/subado/tmp/pipes/c"; // compiled c.c
const int ENOUGH = (int)((ceil(log10(pipefd[1])) + 1) * sizeof(char));
char str[ENOUGH];
sprintf(str, "%d", pipefd[1]);
execl(child, child, str, NULL);
} else {
close(pipefd[1]);
int statloc;
waitpid(-1, &statloc, 0);
char buf[10];
read(pipefd[0], buf, sizeof(buf));
printf("Parent receive: %s", buf);
close(pipefd[0]);
}
return 0;
}
现在输出是:
fd = 4
fd = 4
Child send: 1000 - 7?
Parent receive: 1000 - 7?
有人可以解释一下为什么我收到
Bad file descriptor
错误吗?
C 和 Python 父程序有什么区别? 我不明白为什么我的 Python 代码不起作用。
解决方案: 我添加了
os.set_inheritable(w, True)
之前
os.execl(name, name, str(w))
这修复了我的代码,因为该文件
os.pipe()
返回的描述符默认是不可继承的。
谢谢dimich!
根据
os.pipe()
文档:
3.4 版中的更改:新的文件描述符现在是不可继承的。
这意味着文件描述符在执行新程序时在子进程中关闭。
您可以使用
os.set_inheritable(w, True)
使描述符可继承。