C:带有管道的线程之间的连接,需要同步吗?

时间:2018-01-18 00:20:19

标签: c synchronization pthreads pipe polling

我在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获得回复,但我的问题是:这是正确的方法吗?我的信念是我错过了关于阅读功能的一些内容。

2 个答案:

答案 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 queuesdatagram socket pair