首页 文章

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

提问于
浏览
0

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

-thread 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获得响应,但我的问题是: is this the correct way? 我的信念是我遗漏了一些关于读取功能的东西 .

2 回答

  • 0

    “[我]这是正确的方法[通过FIFO读取可变长度异步消息,一次处理一个]?”

    不,您不需要将通过FIFO发送可变长度消息的单个 生产环境 者同步到单个消费者,以便一次处理一个消息 .

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

    有需要一次读取一个字符的记录终止消息,但可以在本地缓冲部分消息 - 想想 stdio 将字节流转换为行的内容 . 只有一个消费者的约束使一些事情变得简单 .

    “[我]这是正确的方式[在线程之间发送可变长度的异步消息]?”

    它可以使用但可能并不理想 .

    面向消息的排队通道可能更适合这里:message queuesdatagram socket pair .

  • 0

    谢谢大家的答案 . 我已经找到了解决方案,不知道它是否在风格上是正确的但是效果非常好,使用非阻塞方式的读取功能 . 所以只需要在main中配置管道:

    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]!='\0' && offset < sizeof(string))
    
        work_with_message(string)....
    

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

相关问题