C:线程之间的FIFO,写入和读取字符串

Posted

技术标签:

【中文标题】C:线程之间的FIFO,写入和读取字符串【英文标题】:C: Fifo between threads, writing and reading strings 【发布时间】: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)工作。有人知道如何解决链接问题吗?我在网上查看过,但我发现的所有解决方案都可能在旧版本上很好,因为选项卡和选项键不同。

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

【问题讨论】:

修正了缩进,使用代码按钮同时突出显示较大的代码块。 `` 语法用于内联代码。 【参考方案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 以了解更多详细信息。

【讨论】:

以上是关于C:线程之间的FIFO,写入和读取字符串的主要内容,如果未能解决你的问题,请参考以下文章

退格字符被添加到 FIFO

带有 fifo 的线程

LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息

拦截先进先出

字符集之间转换读取和写入

Python3 - 读写字节数据