You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C与Python通过FIFO进行IPC时双进程阻塞或触发BlockingIOError问题求助

问题根因分析
  • FIFO打开模式错误:你在C和Python侧都使用O_RDWR模式打开FIFO,违背了FIFO半双工的设计逻辑。FIFO标准用法是单侧只读、另一侧只写,读写模式打开时进程会同时持有读、写两端的引用,导致内核无法触发正常的管道唤醒、EOF检测逻辑,就算有写入数据也可能因为缓存、引用计数异常导致读操作永久阻塞。
  • FIFO打开顺序不匹配:你当前C侧仅打开了/tmp/Pipe_01,没有提前打开/tmp/Pipe_02的读端,虽然用O_RDWR绕过了打开阶段的阻塞,但后续读写逻辑仍然因为端引用异常卡住。
  • 子进程文件描述符继承问题:C进程fork出子进程后,父进程打开的所有文件描述符会默认被子进程继承,如果你打开FIFO的fd没有设置FD_CLOEXEC标志,execv启动Python后这些fd仍会保留,导致FIFO的端引用计数混乱,永远不会触发可读/可写事件。
解决方案

1. 调整C侧逻辑

  • 两个FIFO严格按单向模式打开:
    • /tmp/Pipe_01是C写、Python读,C侧用O_WRONLY模式打开
    • /tmp/Pipe_02是Python写、C读,C侧用O_RDONLY模式打开
  • 打开FIFO时添加O_CLOEXEC标志,避免子进程继承fd:
    // 打开FIFO示例代码
    int fd_pipe1 = open("/tmp/Pipe_01", O_WRONLY | O_CLOEXEC);
    int fd_pipe2 = open("/tmp/Pipe_02", O_RDONLY | O_CLOEXEC);
    
  • 必须先完成两个FIFO的打开操作,再执行fork+execv启动Python进程;写入数据后调用fsync(fd_pipe1)主动刷入内核缓存,确保Python侧可以立刻读到数据。

2. 调整Python侧逻辑

严格按单向模式阻塞打开FIFO,不需要使用O_RDWR或者非阻塞标志:

#!/usr/bin/python3
import os

# Pipe_01为Python读端,使用只读模式打开
pr = os.open('/tmp/Pipe_01', os.O_RDONLY)
print("Read Opened")
# Pipe_02为Python写端,使用只写模式打开
pw = os.open('/tmp/Pipe_02', os.O_WRONLY)
print("Write Opened")

while True:
    v = os.read(pr, 3)
    # 读返回空字节代表C侧写端已关闭,可直接退出循环
    if not v:
        break
    print("Python read")
    print(v)
    # 向C侧返回数据时,写完可调用os.fsync(pw)刷缓存
    # os.write(pw, 返回给C的数据)

可选:非阻塞读适配

如果确实需要非阻塞读避免进程卡死,捕获BlockingIOError异常处理即可:

#!/usr/bin/python3
import os
import errno

pr = os.open('/tmp/Pipe_01', os.O_RDONLY | os.O_NONBLOCK)
pw = os.open('/tmp/Pipe_02', os.O_WRONLY)

while True:
    try:
        v = os.read(pr, 3)
        if not v:
            break
        print(v)
        # 处理返回逻辑
    except BlockingIOError as e:
        if e.errno == errno.EAGAIN:
            # 无数据时可以休眠或执行其他任务
            os.sleep(0.01)
            continue
        # 其他异常直接抛出
        raise

内容的提问来源于stack exchange,提问作者RTC222

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:24:06