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

C: connection between threads with pipe, synchronization needed?

我正在处理 C 编程中线程之间的管道通信。 我有 2 个线程:

-线程1只是管理一些事件,

-线程2与串口通信;

线程 1 和 2 通过管道通信。

如果有某些条件,"events manager" 线程应该发送一个字符串到 "serial manager",例如pipe[1],它从串行端口和 pipe[0] 进行轮询。 然后如果有来自 pipe[0] 的字符串,它应该完成他的工作。

问题是线程 1 的写入速度比线程 2 的读取速度快。 所以我的问题是:我如何正确地从管道 [0] 中读取?我如何排队?因为如果我简单地以阻塞方式使用读取,只需在线程 2 中键入:

read(pipe[0], string, sizeof(string)-1)

线程2读取所有线程1的过载消息;

我找到的唯一解决方案是创建另一个阻塞线程1的管道(因为线程1在写入后开始读取,读取是阻塞方式),所以线程1等待直到线程2完成才工作(这个很有用,因为我可以从 thread2 获得响应),但我的问题是:这是正确的方法吗? 我确信我遗漏了一些关于读取函数的信息。

谢谢大家的回答。 我找到了解决方案,不知道它在风格上是否正确,但它工作得很好,以非阻塞方式使用读取功能。所以只需在主管道中配置管道:

fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK);

然后确保从 thread1 写入字符串加上 '\0' 字符:

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]!='[=12=]' && offset < sizeof(string))

    work_with_message(string)....

就是这样,告诉我你的想法;-)

"[I]s this the correct way [to read variable-length asynchronous messages over a FIFO, processing them one at a time]?"

不,您不需要同步单个生产者通过 FIFO 向单个消费者发送可变长度消息以一次处理一个消息。

如您在自己的回答中所述,您可以在消息中添加记录终止符。您可以实现一个简单的协议来描述每条消息的长度 (c.f.netstrings).

这里有很多你可以借鉴的练习。例如,您不需要一次读取一个字符的记录终止消息,但可以在本地缓冲部分消息 — 想一想 stdio 将字节流转换为行的做法。只有一个消费者的限制使一些事情变得简单。

"[I]s this the correct way [to send variable-length asynchronous messages between threads]?"

它可以使用,但可能不理想。

面向消息的队列通道可能更适合这里:message queues or a datagram socket pair