我在C编程中处理线程之间的管道通信。 我有2个帖子:
- 线程1只管理一些事件,
-thread 2与串口通信;
线程1和2与管道通信。
"活动经理"线程如果有某些条件应该发送一个字符串给"串行管理器"与...管道[1],从串口和管道[0]轮询。 然后,如果有一个来自pipe [0]的字符串,它应该完成他的工作。
问题是线程1的写入速度比线程2的读取速度快。 所以我的问题是:我如何正确读取管道[0]?我怎么有队列?因为如果我只是在阻塞方式中使用read只需输入线程2:
read(pipe[0], string, sizeof(string)-1)
线程2读取所有线程1的重载消息;
我找到的唯一解决方案是创建另一个阻塞线程1的管道(因为线程1在写入后开始读取,读取是阻塞方式),因此线程1等待直到线程2完成工作(这很有用)因为我可以从thread2获得回复,但我的问题是:这是正确的方法吗?我的信念是我错过了关于阅读功能的一些内容。
答案 0 :(得分:0)
谢谢大家的答案。 我已经找到了解决方案,不知道它是否在风格上是正确的但是效果非常好,使用非阻塞方式的读取功能。所以只需要在main中配置管道:
fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK);
然后确保从thread1写入字符串加'\ 0'char:
write (pipe_fd[1], string, sizeof(string)+1);
最后,thread2中的读取应该就像这个
int n_bytes, offset;
int pres;
char ch[2];
string[256];
pres = poll (....);
if (pres > 0){
...
...
/* if it's the pipe_fd[0] ...*/
offset = 0;
do{
n_bytes = read(pipe_fd[0], &ch, 1);
string[offset] = ch[0];
offset += n;
}while(n>0 && ch[0]!='\0' && offset < sizeof(string))
work_with_message(string)....
就是这样,告诉我你的想法; - )
答案 1 :(得分:0)
&#34; [我]这是正确的方式 [通过FIFO读取可变长度异步消息,一次处理一个] ?&#34;
不,您不需要将通过FIFO发送可变长度消息的单个生产者同步到单个消费者,以便一次处理一个消息。
正如您在自己的答案中记录的那样,您可以在消息中添加记录终止符。您可以实现一个描述每条消息长度的简单协议(c.f。netstrings)。
你可以在这里借用很多先前的练习。例如,您不需要一次读取一个字符的记录终止消息,但可以在本地缓冲部分消息 - 考虑stdio
将字节流转换为行的内容。只有一个消费者的约束使一些事情变得简单。
&#34; [我]这是正确的方式 [在线程之间发送可变长度的异步消息] ?&#34;
它可以使用但可能并不理想。
面向消息的排队频道可能更适合此处:message queues或datagram socket pair。