C:线程之间的Fifo,写入和读取字符串
亲爱的互联网,你好,
我正在编写一个小程序,除其他外,它会将收到的所有命令写入日志文件。
为此,我想使用一个仅尝试从管道读取数据的线程,而主线程将在需要时写入该管道。
由于我不知道每个字符串命令的长度,因此我考虑写入和读取指向 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)工作。有人知道如何解决链接问题吗?我在网上查看过,但我找到的只是可能适用于旧版本的解决方案,因为选项卡和选项键不同。
无论如何,感谢一群互联网! 约那坦
Hello once more dear internet,
I am writing a small program that, among other things, writes to a log file all of the commands it received.
To do that, I want to use a thread that will only attempt to read from a pipe, while the main thread will write into that pipe whenever it should.
Since I don't know the length of each string command, I thought about writing and reading the pointer to the char buf[MAX_MESSAGE_LEN]
.
Since what I’ve tried so far doesn't work, I’ll post my best effort :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*));
and the thread does this:
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);
(Sorry if this doesn't indent, I can't seem to figure out this editor...)
oh, and pipe_fd[2]
is a global parameter.
So, any help with this, either by the way I thought of, or another way I could read strings without knowing the length, would be much appreciated.
On a side note, I’m working on Eclipse IDE C/C++, version 1.2.1 and I can't seem to set up the compiler so it will link the pthread library to my project. I've resorted to writing my own Makefile to make it (pun intended :P) work. Anyone knows how to fix the link issue? I’ve looked online, but all I find are solutions that are probably good on an older version because the tabs and option keys are different.
Anyways, Thanks a bunch internet!
Yonatan
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在我看来,如果您碰巧读或写得太多,那么您的代码就会终止。你应该有,而 success_read < MAX_MSGLEN 或 sizeof(str)。
Seems to me like if you just happened to read or write a little too much, then your code would terminate. You should have, while success_read < MAX_MSGLEN or sizeof(str).
你真的需要一个额外的线程吗?正如您所发现的,添加线程会大大增加复杂性......在这种情况下,写入管道不太可能比写入文件快得多 - 事实上,在实践中它很可能最终会变慢,因为 write() 没有 fprintf() 和朋友那样的缓冲。最好的解决方案可能就是直接写入日志文件......
Do you really need an extra thread for this? As you're finding, adding threads increases complexity a lot... in this case, writing to the pipe is not likely to be much faster than writing to the file - and in fact, it may well end up being slower in practice, since
write()
doesn't have the buffering thatfprintf()
and friends do. The best solution may be simply to write to the logfile directly...您尝试过套接字对(AF_UNIX,SOCK_DGRAM)吗?它本质上是可靠的,并且还会为您分隔消息。
在您的情况下,您必须确保 MAX_MESSAGE_LEN 小于 PIPE_BUF,即管道()内部缓冲区的平台限制。
显然,将指针的发送/接收更改为实际字符串的发送,例如:
Have you tried socketpair(AF_UNIX,SOCK_DGRAM)? It is reliable by its nature and also would delimit messages for you.
In your case, you have to make sure that MAX_MESSAGE_LEN is less than PIPE_BUF, the platform's limit for pipe()'s internal buffer.
And obviously, change sending/recving of pointer into sending of the actual string, e.g.:
为什么要按 4 或 8 字节的
sizeof(char*)
字节块读取和写入数据?您不必被迫读取和写入相同数量的字节!如果您的问题是在读取线程中没有接收到数据,则应该考虑在写入后使用
sync()
进行同步。Why do you read and write data by chunks of
sizeof(char*)
bytes that is 4 or 8 bytes? You are not forced to read and write by the same number of bytes!If your problem is that you do not receive data in the reading thread, you should think about syncing after the write, using
sync()
.您没有在循环中更新
success_write
。You are not updating
success_write
in the loop.您可以创建一个简单的协议来通过 FIFO/管道进行通信。写入器线程将单个字节写入 FIFO 以指示消息长度,然后写入可变长度消息。阅读器将读取单个字节以了解消息的长度,然后发出指定消息长度的后续读取命令。
您可能需要查看此答案类似的有关 FIFO 的问题了解更多详细信息。
You could create a simple protocol to communicate over the FIFO/pipe. The writer thread writes a single byte to the FIFO to indicate the message length and then writes the variable length message. The reader will read a single byte to learn the length of the message and then issue a subsequent read command for the specified message length.
You may want to check out this answer to a similar question on FIFOs for more details.