在 Linux 中使用 fgets 在 C 程序中命名管道删除数据
Named Pipe Dropping Data in C Program Using fgets in Linux
我正在尝试使用 fgets 从 C 程序 (gcc -std=c99) 中的命名管道中提取数据。我在命令行创建了管道,我可以看到它存在于文件系统中,并且在使用 "ls -la" 时用 p 停放并且权限设置为任何人都可以使用。
prw-rw-rw- 1 www-data www-data 0 Dec 23 00:39 mypipe
我正在使用一个简单的脚本将数据发送到管道:
#script
myPipe="/tmp/mypipe"
for j in {0..255}
do
# echo "C $j" #when this is enabled slightly more data gets through
echo "C $j" >> $myPipe
# sleep 0.00000000000001 #when this is enabled all the data gets through
done
我的程序试图从此管道读取的循环是:
void * reader(){
int messages = 0; // keep track of how many messages we process
char buf[PIPE_BUF]; buf[0] = 0; //#defined PIPE_BUF 1024
int x=100, y=101, z=102, count=103; //initialized to unlikely initial input results
char linetag[PIPE_BUF]; linetag[0] = 0; //space to store the data label
char * pScan = NULL;
FILE *myStream ;
syslog (LOG_INFO, "Reader started\n");
myStream = fopen(pipeName, "r");
if ( myStream == NULL ) {
syslog (LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName ) ;
return 0;
}
while (1) {
//>>> This was the problem and removing it seems to fix the issue
//freopen(pipeName, "r", myStream); <<<<This was the problem !!!!
pScan==buf;
syslog (LOG_INFO, "readp-1:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
while ( (pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
if (pScan == NULL){syslog (LOG_WARNING, "ERROR NULL pScan error");}
syslog (LOG_INFO, "readp-2:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
count = sscanf(pScan, "%s %d %d %d", linetag, &x, &y, &z);
syslog (LOG_INFO, "readp-3:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
messages++;
}
}
当我运行上面写的脚本时,我的系统日志显示如下:
Reader started
readp-1:msg:0 >><<>>(null)<< pBuf=0xbe885df4, pScan=(nil), count=103, tag=, x=100, y=101, z=102
readp-2:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=103, tag=, x=100, y=101, z=102
readp-3:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-1:msg:1 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-2:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-3:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-1:msg:2 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-2:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-3:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-1:msg:3 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-2:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-3:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-1:msg:4 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-2:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-3:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-1:msg:5 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-2:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-3:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-1:msg:6 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-2:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-3:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-1:msg:7 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-2:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-3:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-1:msg:8 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-2:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-3:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-1:msg:9 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-2:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-3:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-1:msg:10 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-2:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-3:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-1:msg:11 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-2:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-3:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-1:msg:12 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-2:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-3:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-1:msg:13 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-2:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-3:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-1:msg:14 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-2:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-3:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-1:msg:15 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-2:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-3:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-1:msg:16 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-2:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-3:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-1:msg:17 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-2:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-3:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-1:msg:18 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-2:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-3:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-1:msg:19 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-2:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-3:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-1:msg:20 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-2:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-3:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
readp-1:msg:21 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
数据分析似乎与行首的 'C' 正确对齐。如果在我的脚本中,我启用本地终端 echo
到屏幕,那么我会减少行数。如果我启用 sleep 0.00000000000001
我就可以读取所有数据。我真的需要它 运行 全速运行并且讨厌通过睡眠来减慢速度。我只是超过 运行 一个缓冲区吗?如果是,可以增加缓冲区大小吗?我真的很困惑。顺便说一句,我使用的是 fgets 而不是 fscanf,因为我最终需要添加 fastcgi 并且 fsastcgi 似乎缺乏对 fscanf 的支持(注意在这个测试中我使用的是标准 io 库,我没有在 fastcgi 中链接,我不包括"fcgi/include/fcgi_stdio.h" 在此测试中,因此没有覆盖默认库)。任何使它可靠和高效的方向将不胜感激。
FIFO 是有趣(奇特)的文件。一个读取进程在打开时阻塞,直到有一个写入器;一个写入进程在打开时阻塞,直到出现 reader。如果没有作者,reader 将得到 EOF;此时,它必须关闭 FIFO 并重新打开它以允许更多的写入器。如果没有readers或writer,则丢弃FIFO的内容。在您的 shell 脚本中,您重复打开和关闭 FIFO。您最好将 >> $myPipe
移动到循环的 done
行,这样 FIFO 打开一次,然后写入所有消息,然后 FIFO 关闭。
你的代码很奇特。这一行有问题:
while ((pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
我看到两个问题。不太严重的是你在空循环body之后有一个空语句。除了向有经验的 reader 表明您对您的 C 代码没有信心之外,这不会做任何有害的事情。 {}
就足够了;这是一个空循环 body。下一行用分号代替 {}
是约定俗成的。
更严重的问题是,如果你进入循环,你将无限期地留在循环中。一旦 myStream
报告 EOF(通过从 fgets()
返回 NULL
,它将无限期地继续这样做(除非你在 Linux 并且输入设备实际上是一个终端 -这对我来说是一个单独的痛点。
问题中的代码似乎是在被问到后被hack了,循环顶部的freopen()
行被注释掉了,这就是'fixed'的问题。这是可以解释的。当 FIFO 关闭重新打开时,内容被丢弃。
更好的代码可能看起来更像这样。它将管道名称直接传递给函数(尽可能避免使用全局变量)。如果打开 FIFO 失败,该函数仅 returns。返回 NULL 的函数没有明显的需要或好处(写作 0
— 没关系;我也这样做),所以它现在是一个 void
函数。函数声明应该在 header 文件中,而不是在代码中内联。
总的来说,我会将大部分变量移动到更接近它们首次使用的位置——只有 messages
会留在无限循环之外。会有一个header来声明各种函数
#include <syslog.h>
#include <stdio.h>
#define PIPE_BUF 1024
extern void reader(const char *pipeName);
void reader(const char *pipeName)
{
int messages = 0;
char buf[PIPE_BUF];
int x = 100, y = 101, z = 102, count = 103;
char linetag[PIPE_BUF];
syslog(LOG_INFO, "Reader started\n");
while (1)
{
FILE *myStream = fopen(pipeName, "r");
if (myStream == NULL)
{
syslog(LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName);
return;
}
while (fgets(buf, sizeof(buf), myStream) != 0)
{
count = sscanf(buf, "%s %d %d %d", linetag, &x, &y, &z);
syslog(LOG_INFO, "readp-3:msg:%i >>%s<< count=%i, tag=%s, x=%d, y=%d, z=%d\n",
messages, buf, count, linetag, x, y, z);
messages++;
}
fclose(myStream);
}
/* NOTREACHED */
syslog(LOG_INFO, "Reader finished\n");
}
我正在尝试使用 fgets 从 C 程序 (gcc -std=c99) 中的命名管道中提取数据。我在命令行创建了管道,我可以看到它存在于文件系统中,并且在使用 "ls -la" 时用 p 停放并且权限设置为任何人都可以使用。
prw-rw-rw- 1 www-data www-data 0 Dec 23 00:39 mypipe
我正在使用一个简单的脚本将数据发送到管道:
#script
myPipe="/tmp/mypipe"
for j in {0..255}
do
# echo "C $j" #when this is enabled slightly more data gets through
echo "C $j" >> $myPipe
# sleep 0.00000000000001 #when this is enabled all the data gets through
done
我的程序试图从此管道读取的循环是:
void * reader(){
int messages = 0; // keep track of how many messages we process
char buf[PIPE_BUF]; buf[0] = 0; //#defined PIPE_BUF 1024
int x=100, y=101, z=102, count=103; //initialized to unlikely initial input results
char linetag[PIPE_BUF]; linetag[0] = 0; //space to store the data label
char * pScan = NULL;
FILE *myStream ;
syslog (LOG_INFO, "Reader started\n");
myStream = fopen(pipeName, "r");
if ( myStream == NULL ) {
syslog (LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName ) ;
return 0;
}
while (1) {
//>>> This was the problem and removing it seems to fix the issue
//freopen(pipeName, "r", myStream); <<<<This was the problem !!!!
pScan==buf;
syslog (LOG_INFO, "readp-1:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
while ( (pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
if (pScan == NULL){syslog (LOG_WARNING, "ERROR NULL pScan error");}
syslog (LOG_INFO, "readp-2:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
count = sscanf(pScan, "%s %d %d %d", linetag, &x, &y, &z);
syslog (LOG_INFO, "readp-3:msg:%i >>%s<<>>%s<< pBuf=%p, pScan=%p, count=%i, tag=%s, x=%d, y=%d, z=%d\n", messages, buf, pScan, buf, pScan, count, linetag, x,y,z);
messages++;
}
}
当我运行上面写的脚本时,我的系统日志显示如下:
Reader started
readp-1:msg:0 >><<>>(null)<< pBuf=0xbe885df4, pScan=(nil), count=103, tag=, x=100, y=101, z=102
readp-2:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=103, tag=, x=100, y=101, z=102
readp-3:msg:0 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-1:msg:1 >>C 0#012<<>>C 0#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-2:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=0, y=101, z=102
readp-3:msg:1 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-1:msg:2 >>C 1#012<<>>C 1#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-2:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=1, y=101, z=102
readp-3:msg:2 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-1:msg:3 >>C 10#012<<>>C 10#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-2:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=10, y=101, z=102
readp-3:msg:3 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-1:msg:4 >>C 11#012<<>>C 11#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-2:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=11, y=101, z=102
readp-3:msg:4 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-1:msg:5 >>C 15#012<<>>C 15#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-2:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=15, y=101, z=102
readp-3:msg:5 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-1:msg:6 >>C 16#012<<>>C 16#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-2:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=16, y=101, z=102
readp-3:msg:6 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-1:msg:7 >>C 18#012<<>>C 18#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-2:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=18, y=101, z=102
readp-3:msg:7 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-1:msg:8 >>C 24#012<<>>C 24#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-2:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=24, y=101, z=102
readp-3:msg:8 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-1:msg:9 >>C 39#012<<>>C 39#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-2:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=39, y=101, z=102
readp-3:msg:9 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-1:msg:10 >>C 50#012<<>>C 50#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-2:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=50, y=101, z=102
readp-3:msg:10 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-1:msg:11 >>C 70#012<<>>C 70#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-2:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=70, y=101, z=102
readp-3:msg:11 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-1:msg:12 >>C 81#012<<>>C 81#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-2:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=81, y=101, z=102
readp-3:msg:12 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-1:msg:13 >>C 108#012<<>>C 108#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-2:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=108, y=101, z=102
readp-3:msg:13 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-1:msg:14 >>C 119#012<<>>C 119#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-2:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=119, y=101, z=102
readp-3:msg:14 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-1:msg:15 >>C 136#012<<>>C 136#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-2:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=136, y=101, z=102
readp-3:msg:15 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-1:msg:16 >>C 155#012<<>>C 155#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-2:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=155, y=101, z=102
readp-3:msg:16 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-1:msg:17 >>C 172#012<<>>C 172#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-2:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=172, y=101, z=102
readp-3:msg:17 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-1:msg:18 >>C 193#012<<>>C 193#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-2:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=193, y=101, z=102
readp-3:msg:18 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-1:msg:19 >>C 213#012<<>>C 213#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-2:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=213, y=101, z=102
readp-3:msg:19 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-1:msg:20 >>C 233#012<<>>C 233#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-2:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=233, y=101, z=102
readp-3:msg:20 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
readp-1:msg:21 >>C 246#012<<>>C 246#012<< pBuf=0xbe885df4, pScan=0xbe885df4, count=2, tag=C, x=246, y=101, z=102
数据分析似乎与行首的 'C' 正确对齐。如果在我的脚本中,我启用本地终端 echo
到屏幕,那么我会减少行数。如果我启用 sleep 0.00000000000001
我就可以读取所有数据。我真的需要它 运行 全速运行并且讨厌通过睡眠来减慢速度。我只是超过 运行 一个缓冲区吗?如果是,可以增加缓冲区大小吗?我真的很困惑。顺便说一句,我使用的是 fgets 而不是 fscanf,因为我最终需要添加 fastcgi 并且 fsastcgi 似乎缺乏对 fscanf 的支持(注意在这个测试中我使用的是标准 io 库,我没有在 fastcgi 中链接,我不包括"fcgi/include/fcgi_stdio.h" 在此测试中,因此没有覆盖默认库)。任何使它可靠和高效的方向将不胜感激。
FIFO 是有趣(奇特)的文件。一个读取进程在打开时阻塞,直到有一个写入器;一个写入进程在打开时阻塞,直到出现 reader。如果没有作者,reader 将得到 EOF;此时,它必须关闭 FIFO 并重新打开它以允许更多的写入器。如果没有readers或writer,则丢弃FIFO的内容。在您的 shell 脚本中,您重复打开和关闭 FIFO。您最好将 >> $myPipe
移动到循环的 done
行,这样 FIFO 打开一次,然后写入所有消息,然后 FIFO 关闭。
你的代码很奇特。这一行有问题:
while ((pScan = fgets(buf, PIPE_BUF, myStream)) == NULL){};
我看到两个问题。不太严重的是你在空循环body之后有一个空语句。除了向有经验的 reader 表明您对您的 C 代码没有信心之外,这不会做任何有害的事情。 {}
就足够了;这是一个空循环 body。下一行用分号代替 {}
是约定俗成的。
更严重的问题是,如果你进入循环,你将无限期地留在循环中。一旦 myStream
报告 EOF(通过从 fgets()
返回 NULL
,它将无限期地继续这样做(除非你在 Linux 并且输入设备实际上是一个终端 -这对我来说是一个单独的痛点。
问题中的代码似乎是在被问到后被hack了,循环顶部的freopen()
行被注释掉了,这就是'fixed'的问题。这是可以解释的。当 FIFO 关闭重新打开时,内容被丢弃。
更好的代码可能看起来更像这样。它将管道名称直接传递给函数(尽可能避免使用全局变量)。如果打开 FIFO 失败,该函数仅 returns。返回 NULL 的函数没有明显的需要或好处(写作 0
— 没关系;我也这样做),所以它现在是一个 void
函数。函数声明应该在 header 文件中,而不是在代码中内联。
总的来说,我会将大部分变量移动到更接近它们首次使用的位置——只有 messages
会留在无限循环之外。会有一个header来声明各种函数
#include <syslog.h>
#include <stdio.h>
#define PIPE_BUF 1024
extern void reader(const char *pipeName);
void reader(const char *pipeName)
{
int messages = 0;
char buf[PIPE_BUF];
int x = 100, y = 101, z = 102, count = 103;
char linetag[PIPE_BUF];
syslog(LOG_INFO, "Reader started\n");
while (1)
{
FILE *myStream = fopen(pipeName, "r");
if (myStream == NULL)
{
syslog(LOG_INFO, "Could not open pipe %s as input to Cota\n", pipeName);
return;
}
while (fgets(buf, sizeof(buf), myStream) != 0)
{
count = sscanf(buf, "%s %d %d %d", linetag, &x, &y, &z);
syslog(LOG_INFO, "readp-3:msg:%i >>%s<< count=%i, tag=%s, x=%d, y=%d, z=%d\n",
messages, buf, count, linetag, x, y, z);
messages++;
}
fclose(myStream);
}
/* NOTREACHED */
syslog(LOG_INFO, "Reader finished\n");
}