Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send message (in C) from one thread to another?

I'm trying to send a message from one thread to another. Each thread knows the thread ID of the other. How can I send a message between them?

I've already seen some proposed solutions (message queue, anonymous pipe, etc.) but honestly I didn't get them to work. Obviously I didn't understand the previous descriptions enough, hence this topic.

So to sum up, just the shortest possible way to send, let's say a message "Hello!" from thread to another thread, make the 2nd thread show it on stderr, and than send back to 1st thread message 'Hello back!'.

It's probably very easy and I didn't do a good job of researching, but I've been stuck for some time now, and can't find decent way to do this.

like image 968
Hisu Avatar asked Nov 27 '25 05:11

Hisu


1 Answers

An example, it's pretty simple — first make a pipe with pipe(). It creates two file descriptor — one for reading, and the second for writing. Here we calling it two times to have both read and write sides. Then we calling fork (that makes a second thread), and write/read messages through the pipes we created.

#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);
        }
    }
}
like image 174
Hi-Angel Avatar answered Nov 29 '25 19:11

Hi-Angel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!