我正在尝试让C进程创建一个python子进程,并使用两个并行FIFO双向通信。我也是分别读取python进程的标准输出(用于记录目的)。
计划是让Python和C程序完全独立运行,偶尔也会相互传递数据。
然而,我在使用从C到python的FIFO工作时遇到了很多麻烦,输出本身让我感到困惑。基本上我不知道为什么我的代码正在做它正在做的事情,我确信这是因为我根本不理解管道。
C代码:
int main() {
printf("*** Starting main program ***\n");
FILE *subprocOut = popen("python3 receiver.py", "r");
// Make the fifo that we will write to and python will read
const char *fifo1Name = "/tmp/demo1.fifo";
int result = mkfifo(fifo1Name, S_IRWXU);
if (result == 0) {
printf("fifo1 successfully created!\n");
}
// Try to open fifo1
FILE *fifo1 = fopen(fifo1Name, "w");
if (fifo1) {
printf("fifo1 successfully opened!\n");
}
// Try to open fifo2 (created and written to by python)
const char *fifo2Name = "/tmp/demo2.fifo";
FILE *fifo2 = fopen(fifo2Name, "r");
if (fifo2) {
printf("fifo2 successfully opened!\n");
}
// Various buffers
const int bufSize = 1024;
char buf1[bufSize]; // Used to read stdout of python process
char buf2[bufSize]; // Used to read fifo2
int running = 1;
while (running) {
printf("running...\n");
// Write to the fifo (will be read by python script)
const char* message = "Greetings from C!\n";
fwrite(message, sizeof(char), strlen(message), fifo1);
// Read from the fifo (contains output from python script)
fread(buf2, sizeof(char), bufSize, fifo2);
// Print the fifo output from python
printf("[FIFO] %s\n", buf2);
// Get the stdout of the python process
if (fgets(buf1, bufSize, subprocOut) != NULL) {
for (int i = bufSize; i >= 0; i--) {
if (buf1[i] == '\n') {
buf1[i] = '\0';
break;
}
}
printf("[PYTHON] %s\n", buf1);
// If python printed a special token the whole program should terminate
if (strncmp(buf1, "%TERMINATE%", bufSize) == 0) {
running = 0;
}
}
}
// Close and delete both fifos
fclose(fifo1);
unlink(fifo1Name);
fclose(fifo2);
unlink(fifo2Name);
printf("*** Terminating main program ***\n");
return 0;
}
Python代码:
# Make fifo2
try:
os.unlink('/tmp/demo2.fifo')
except FileNotFoundError:
pass
os.mkfifo('/tmp/demo2.fifo')
print('fifo2 successfully created!')
# Open fifo1 (we will read from this)
fifo1 = open('/tmp/demo1.fifo', 'r')
print('fifo1 successfully opened!')
# Open fifo2 (we will write to this)
fifo2 = open('/tmp/demo2.fifo', 'w')
print('fifo2 successfully opened!')
sys.stdout.flush()
# Count how many seconds our program has been running
timeTaken = 0
while True:
print('Running...')
fifo2.write('hello!\n')
# THESE LINES CAUSE PROGRAM TO HANG
#
# lines = fifo1.readlines()
# for line in lines:
# print('RECEIVED:', line)
sys.stdout.flush()
# Pretend the sleep is caused by heavy computation
time.sleep(1)
timeTaken += 1
# If we've been running for 3 seconds, pull the plug
if timeTaken == 3:
print('%TERMINATE%')
break
输出:
*** Starting main program ***
fifo1 successfully opened!
fifo2 successfully opened!
running...
[FIFO] hello!
hello!
hello!
[PYTHON] fifo2 successfully created!
running...
[FIFO] hello!
hello!
hello!
[PYTHON] fifo1 successfully opened!
running...
[FIFO] hello!
hello!
hello!
[PYTHON] fifo2 successfully opened!
running...
[FIFO] hello!
hello!
hello!
[PYTHON] Running...
running...
[FIFO] hello!
hello!
hello!
[PYTHON] Running...
running...
[FIFO] hello!
hello!
hello!
[PYTHON] Running...
running...
[FIFO] hello!
hello!
hello!
[PYTHON] %TERMINATE%
Process finished with exit code 13
python代码中无限循环中注释掉的行会导致程序因某种原因挂起。我似乎无法读取从C到python的FIFO。
尽管在python中的无限循环之前调用了flush,但是与创建/打开管道有关的[PYTHON]
输出与[FIFO]
调用交错。
此外,hello!
每次迭代时都会打印3次,即使它应该每次打印一次,就像[PYTHON] Running...
一样。
此外,为什么{C}程序中running...
的打印频率与[PYTHON] Running...
一样频繁? python程序在循环的每次迭代中都会休眠一秒,但是C程序应该继续正确吗?是什么导致C中的主循环阻塞?
最后,我的C程序中的fclose()
和unlink()
调用似乎导致了SIGPIPE信号,但是我应该如何关闭和删除FIFO呢?