putc()在通过使用popen打开的管道发送数据时会阻塞

putc()在通过使用popen打开的管道发送数据时会阻塞,c,pipe,C,Pipe,首先我有下面的宏 #define MSG_UPDATE_DATA 70 然后用popen SensServer = popen("./SensServer", "w") ; 在下面使用putc(…)函数写入管道的代码中,该函数使程序块和下面的代码行不执行 void requestTempAndPress(int pid) { printf("Temp and presure requested. msg_type: %d\n", MSG_UPDATE_DATA); int n

首先我有下面的宏

#define MSG_UPDATE_DATA 70
然后用
popen

SensServer = popen("./SensServer", "w") ;
在下面使用
putc(…)
函数写入管道的代码中,该函数使程序块和下面的代码行不执行

void requestTempAndPress(int pid) {
    printf("Temp and presure requested. msg_type: %d\n", MSG_UPDATE_DATA);
    int n = putc(MSG_UPDATE_DATA, SensServer);

    printf("Data sent: %d\n", MSG_UPDATE_DATA);
}
它输出所需的
温度和压力。消息类型:70
很好。但不是“已发送数据…”行。

根据手册页

  • 是一个
    fd
    ,类型
    int
  • 需要一个
    文件*流
    作为参数
因此,最可能的情况是,在代码中,您向
putc()
提供了错误类型的参数,从而产生了问题。

给定信息(并且缺少示例程序),这听起来像是一个询问如何使管道不阻塞的问题。这一点以前已经讨论过,通常用于非阻塞读取,例如

  • (C++)
第一个链接提到了
O_NONBLOCK
标志,手册页面称该标志可应用于读写

但是,使用使管道使用缓冲I/O,而由
fcntl
处理的操作是非缓冲的
read
和(您确实不能将两者混合使用)。如果程序被更改为使用低级别(如第一个链接的示例中所示),并且始终使用非缓冲I/O,它将给出预期的行为

以下是有关该主题的更一般性讨论的链接:

另一方面(注意注释),例如,如果程序片段是某个较大系统的一部分(期望服务器及时响应),则会遇到问题。片段正在跨越管道写入单个字符。但是,
popen
打开一个(块)缓冲流。除非提供一些帮助,否则不会以单字符写入的方式将任何内容直接发送到服务器。例如,可以在每次
putc
之后刷新输出流,例如

fflush(SensServer);
或者,可以在成功调用
popen
后立即更改流,使其无缓冲,例如,使用:

以下是有关管道中缓冲的进一步阅读链接:


    • 问题是由于我在父进程中初始化了变量SensServer,而不是子进程。这意味着指针是0或者我猜是一个随机的内存位置

      的确:
      FILE*SensServer,*SoundServer而且
      SensServer=popen(“./SensServer”,“w”)
      @hedgepigmart
      pipe()
      返回
      int
      ,而不是
      文件*
      。你想在这里实现什么?将数据发送到SensServerprogram@HedgepigMatt这一部分是可以理解的,但我想问的是为什么将
      文件*
      流称为
      管道
      ?@hedgepigmat好的,
      消息更新数据
      的定义是什么?它是变量还是宏定义?什么是
      SensServer
      ?您能否在问题描述中指定如何打开管道。因为如果您使用popen打开了管道,那么请检查您是否提供了写入标志,因为管道是单向的。您能否提供?
      #define MSG_UPDATE_DATA
      #define MSG_UPDATE_DATA 70
      ,我的笔记本电脑上的互联网已经崩溃了只是一个小提示:我们处理的进程根本没有刷新到标准输出或打印新行,所以我们通过管道将进程传输到它并从中读取,以查看我们是否有缓冲问题(我们确实有缓冲问题:))在许多实现中,您会得到一个核心转储。您的应用程序现在是否按预期工作?
      setvbuf(SensServer, NULL, _IONBF, 0);