使用C ++中的命名管道写入/读取数据流(双精度)

时间:2017-02-17 16:09:46

标签: c++ linux pipe

我正在尝试在Linux环境中用C ++开发一个小应用程序,它执行以下操作:

1)从“黑匣子”的输出中获取数据流(一系列双打数组)。并将其写入管道。黑盒子可以被认为是ADC;

2)从管道读取数据流并将其提供给另一个需要这些数据作为stdin的应用程序;

不幸的是,我无法找到教程或示例。我发现实现这一目标的最佳方法在以下测试平台示例中进行了总结:

#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>

#define FIFO "/tmp/data"

using namespace std;

int main() {

   int fd;
   int res = mkfifo(FIFO,0777);
   float *writer = new float[10];
   float *buffer = new float[10];

   if( res == 0 ) {
      cout<<"FIFO created"<<endl;

      int fres = fork();

      if( fres == -1 ) {
         // throw an error
      }
      if( fres == 0 )
      {
         fd = open(FIFO, O_WRONLY);

         int idx = 1;
         while( idx <= 10) {
            for(int i=0; i<10; i++) writer[i]=1*idx;

            write(fd, writer, sizeof(writer)*10);
         }
         close(fd);
      }
      else
      {
         fd = open(FIFO, O_RDONLY);
         while(1) {
            read(fd, buffer, sizeof(buffer)*10);

            for(int i=0; i<10; i++) printf("buf: %f",buffer[i]);
            cout<<"\n"<<endl;
         }
         close(fd);
      }

   }

   delete[] writer;
   delete[] buffer;

}

问题在于,通过运行这个例子,我没有得到我正在向管道输入的所有10个数组的打印输出,而我总是得到第一个数组(用1填充)。

非常欢迎任何建议/更正/参考,以使其工作并了解更多有关管道行为的信息。

编辑:

对不起伙计们!我在我的代码中发现了一个非常微不足道的错误:在编写器部分的while循环中,我没有递增索引idx ......一旦我纠正它,我得到所有数组的打印输出。 但现在我面临另一个问题:当使用大量数组时,会随机打印出这些数组(整个序列不打印);好像读者部分无法应对作者的速度。这是新的示例代码:

#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>

#define FIFO "/tmp/data"

using namespace std;

int main(int argc, char** argv) {

   int fd;
   int res = mkfifo(FIFO,0777);
   int N(1000);
   float writer[N];
   float buffer[N];

   if( res == 0 ) {
      cout<<"FIFO created"<<endl;

      int fres = fork();

      if( fres == -1 ) {
         // throw an error
      }
      if( fres == 0 )
      {
         fd = open(FIFO, O_WRONLY | O_NONBLOCK);

         int idx = 1;
         while( idx <= 1000 ) {
            for(int i=0; i<N; i++) writer[i]=1*idx;

            write(fd, &writer, sizeof(float)*N);
            idx++;
         }
         close(fd);
         unlink(FIFO);
      }
      else
      {
         fd = open(FIFO, O_RDONLY);
         while(1) {
            int res = read(fd, &buffer, sizeof(float)*N);

            if( res == 0 ) break;
            for(int i=0; i<N; i++) printf(" buf: %f",buffer[i]);
            cout<<"\n"<<endl;

         }
         close(fd);
      }

   }

} 

是否有一些机制可以使write()等待,直到read()仍在从fifo读取数据,或者在这种情况下我是否遗漏了一些微不足道的东西?

感谢那些已经回答我之前版本问题的人,我已经实施了这些建议。

1 个答案:

答案 0 :(得分:0)

"actions": { "Create_file": { "inputs": { "body": "@body('tableCsv0')", "host": { "api": { "runtimeUrl": "https://logic-apis-northeurope.azure-apim.net/apim/ftp" }, "connection": { "name": "@parameters('$connections')['ftp']['connectionId']" } }, "method": "post", "path": "/datasets/default/files", "queries": { "folderPath": "transactions/ready/ecommerce/tickets_test/", "name": "grma_tickets_@{formatDateTime(utcNow(),'yyyyMMdd_hhmmss')}.csv" } }, "runAfter": { "tableCsv0": [ "Succeeded" ] }, "type": "ApiConnection" }, "Execute_stored_procedure": { "inputs": { "host": { "api": { "runtimeUrl": "https://logic-apis-northeurope.azure-apim.net/apim/sql" }, "connection": { "name": "@parameters('$connections')['sql']['connectionId']" } }, "method": "post", "path": "/datasets/default/procedures/@{encodeURIComponent(encodeURIComponent('[Scheduledjob].[GetBArcodesForGRMA]'))}" }, "runAfter": {}, "type": "ApiConnection" }, "tableCsv0": { "inputs": { "columns": [ { "header": "EventDateTime", "value": "@item()?['EventDateTime']" }, { "header": "EventName", "value": "@item()?['EventName']" } ], "format": "csv", "from": "@body('Execute_stored_procedure')['ResultSets']['Table1']" }, "runAfter": { "Execute_stored_procedure": [ "Succeeded" ] }, "type": "Table" } read的参数不正确。正确的:

write

此外,这些函数可能会进行部分读/写操作,因此代码需要检查返回值以确定是否必须继续操作。

不确定为什么write(fd, writer, 10 * sizeof *writer); read(fd, buffer, 10 * sizeof *buffer); 在编写器中循环,这个循环永远不会结束。即使在5GHz CPU上。对读者的评论相同。