C语言基于双FIFO实现CS架构应用时服务端读取请求阻塞问题
问题原因排查
1. FIFO打开顺序导致死锁
- FIFO的默认规则是打开操作会阻塞,直到读写两端都被其他进程打开才会返回成功。如果你的客户端代码逻辑为「先打开
server_to_client读端,再打开client_to_server写端」,而服务端逻辑为「先打开client_to_server读端,再打开server_to_client写端」,就会出现死锁:两端都卡在FIFO打开的步骤,根本没有执行到后续读写数据的逻辑。 - 验证方案:用
ps aux | grep 你的进程名查看两个进程状态,均处于阻塞睡眠状态即可确认该问题。 - 修复方案:统一两端的FIFO打开顺序,比如都优先操作
client_to_server再操作server_to_client;也可以在open时添加O_NONBLOCK参数做非阻塞打开,添加重试逻辑避免死锁。
2. 标准库缓冲区未刷新
- 如果客户端用
fprintf、fwrite等C标准库函数写入client_to_server的文件流,默认会开启全缓冲模式,写入的内容会暂存在进程的用户态缓冲区中,没有真正提交到内核的FIFO管道里,所以服务端读不到任何数据。 - 修复方案:写入完成后调用
fflush(文件流指针)主动刷写缓冲区;也可以直接用系统调用write()写入FIFO,write不会经过标准库缓冲,会直接把数据提交到内核。
3. 新增FIFO操作异常导致客户端提前退出
- 你新增的
server_to_clientFIFO如果权限设置错误、或者路径写错,客户端打开该FIFO失败后直接终止,没有执行到后续写入client_to_server的逻辑,你看到的「客户端已经写入」可能是误判。 - 验证方案:给所有系统调用加错误判断,
open、read、write调用失败时调用perror()打印错误信息,确认每一步逻辑都正常执行。
4. 读取长度不匹配导致阻塞
- 如果服务端
read调用指定的读取长度大于客户端实际写入的长度,且FIFO的写端没有被关闭,read会一直阻塞等待更多数据,并不是FIFO中没有内容。 - 修复方案:两端约定固定长度的消息结构,或者在消息头部加长度字段,服务端先读取长度再读取对应长度的内容;短连接场景也可以在客户端写完数据后直接关闭
client_to_server的写端,触发服务端read返回0。
内容的提问来源于stack exchange,提问作者Iulian Muntean
相关产品推荐
相关产品推荐

