【问题标题】:C: Fifo between threads, writing and reading stringsC:线程之间的FIFO,写入和读取字符串
【发布时间】:2010-06-08 11:21:23
【问题描述】:

亲爱的互联网,你好,

我正在编写一个小程序,除其他外,它将接收到的所有命令写入日志文件。
为此,我想使用一个只尝试从管道读取的线程,而主线程将在任何时候写入该管道。

由于我不知道每个字符串命令的长度,所以我想到了写入和读取指向char buf[MAX_MESSAGE_LEN]的指针。
由于到目前为止我尝试过的方法不起作用,我会尽我最大的努力:P

   char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";  
    if (pipe(pipe_fd) != 0) 
        return -1;  
    pthread_t log_thread;  
    pthread_create(&log_thread,NULL, log_thread_start, argv[2]);  
    success_write = 0;  
    do {  
        write(pipe_fd[1],(void*)&str,sizeof(char*));  
    } while (success_write < sizeof(char*));

线程会这样做:

    char buffer[MAX_MSGLEN];  
    int success_read;  
    success_read = 0;  
    //while(1) {  
        do {  
            success_read += read(pipe_fd[0],(void*)&buffer, sizeof(char*));  
        } while (success_read < sizeof(char*));  
    //}  
    printf("%s",buffer); 

(对不起,如果这不缩进,我似乎无法弄清楚这个编辑器......) 哦,pipe_fd[2] 是一个全局参数。

因此,任何对此的帮助,无论是我想到的方式,还是我可以在不知道长度的情况下读取字符串的另一种方式,将不胜感激。

附带说明,我正在使用 Eclipse IDE C/C++,版本 1.2.1,我似乎无法设置编译器,因此它将 pthread 库链接到我的项目。我已经求助于编写自己的 Makefile 来使它(双关语:P)工作。有人知道如何解决链接问题吗?我在网上查看过,但我发现的所有解决方案都可能在旧版本上很好,因为选项卡和选项键不同。

无论如何,感谢一大堆互联网! 与那丹

【问题讨论】:

  • 修正了缩进,使用代码按钮同时突出显示较大的代码块。 `` 语法用于内联代码。

标签: c pipe pthreads


【解决方案1】:

在我看来,如果你碰巧读或写得太多,那么你的代码就会终止。你应该有,而 success_read

【讨论】:

    【解决方案2】:

    你真的需要一个额外的线程吗?正如您所发现的,添加线程会大大增加复杂性......在这种情况下,写入管道可能不会比写入文件快得多 - 事实上,它最终可能会在实践中变慢,因为write() 没有fprintf() 和朋友所做的缓冲。最好的解决方案可能是直接写入日志文件...

    【讨论】:

      【解决方案3】:

      你试过socketpair(AF_UNIX,SOCK_DGRAM)吗?它本质上是可靠的,也可以为您划定消息。

      在您的情况下,您必须确保 MAX_MESSAGE_LEN 小于 PIPE_BUF,即平台对 pipe() 内部缓冲区的限制。

      显然,将指针的发送/接收更改为实际字符串的发送,例如:

      -   char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";
      +   char str[MAX_MESSAGE_LEN] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";
      
      - write(pipe_fd[1],(void*)&str,sizeof(char*));
      + write(pipe_fd[1],(void*)&str,MAX_MESSAGE_LEN);
      

      【讨论】:

        【解决方案4】:

        为什么要通过 sizeof(char*) 字节块(即 4 或 8 个字节)来读取和写入数据?您不必强制读取和写入相同的字节数!

        如果你的问题是你没有在读取线程中接收到数据,你应该考虑在写入之后同步,使用sync()

        【讨论】:

        • 不,fflush() 用于刷新 stdio 缓冲区。他直接使用 read() 和 write(),绕过了 stdio。
        【解决方案5】:

        您没有在循环中更新success_write

        【讨论】:

          【解决方案6】:

          因此,任何对此的帮助,无论是我想到的方式,还是我可以在不知道长度的情况下读取字符串的另一种方式,将不胜感激。

          您可以创建一个简单的协议来通过 FIFO/管道进行通信。写入器线程将单个字节写入 FIFO 以指示消息长度,然后写入可变长度消息。阅读器将读取单个字节以了解消息的长度,然后针对指定的消息长度发出后续读取命令。

          您可能需要查看此answer 到类似的question FIFO 以了解更多详细信息。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-05
            • 1970-01-01
            • 1970-01-01
            • 2015-01-17
            相关资源
            最近更新 更多