如何从一个线程向另一个线程发送消息(在C中)?

时间:2015-06-13 20:38:43

标签: c multithreading unix pthreads

我试图将消息从一个线程发送到另一个线程。每个线程都知道另一个线程的线程ID。我怎样才能在他们之间发送消息?

我已经看过一些建议的解决方案(消息队列,匿名管道等),但老实说,我没有让它们工作。显然,我对前面的描述不够了解,因此这个话题。

总而言之,只需要尽可能短的发送方式,让我们说一条消息"你好!"从线程到另一个线程,让第二个线程在stderr上显示它,然后发送回第一个线程消息'你好回来!'。

这可能很容易,而且我没有做好研究,但我已经被困了一段时间了,并且找不到合适的方法来做这件事

1 个答案:

答案 0 :(得分:2)

一个例子,它非常简单 - 首先使用pipe()制作一个管道。 It creates two file descriptor - 一个用于阅读,另一个用于写作。在这里,我们两次调用它来同时具有读写端。然后我们调用fork (创建第二个线程),并通过我们创建的管道写/读消息。

#include <poll.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int wait_n_read(int fd, char* buf, int szBuf) {
    struct pollfd pfd = {
        .fd      = fd,
        .events  = POLLIN,
        .revents = 0
    };
    poll(&pfd, 1, -1); //wait for an event
    int ret = read(fd, buf, szBuf);
    if (ret == -1) {
        perror("In read()");
    }
    return ret;
}

main(){
    int chan[4];
    enum{
        thread1_read  = 0, //read end for parent
        thread2_write = 1, //write end for child 
        thread2_read  = 2, //read end for child 
        thread1_write = 3  //write end for parent
    };
    if (pipe(&chan[thread1_read]) == -1 || (pipe(&chan[thread2_read]) == -1)){
        perror("In pipe");
        return 1;
    }
    switch(fork()) {
        case -1:
            perror("In fork()");
            return 1;
        case 0:{ //it's a child
            char buf[256];
            memset(buf, 0, sizeof(buf));
            if (wait_n_read(chan[thread2_read], buf, sizeof(buf)-1) == -1)
                return 1;
            fputs(buf, stderr);
            const char helloback[] = "Hello back\n";
            write(chan[thread2_write], helloback, sizeof(helloback));
            return 0;
        }
        default: { //a parent
            const char hello[] = "Hello\n";
            write(chan[thread1_write], hello, sizeof(hello));
            char buf[256];
            memset(buf, 0, sizeof(buf));
            if (wait_n_read(chan[thread1_read], buf, sizeof(buf-1)) == -1)
                return 1;
            fputs(buf, stderr);
        }
    }
}