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,写入和读取字符串的主要内容,如果未能解决你的问题,请参考以下文章