Reputation: 95
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.
Upvotes: 2
Views: 5248
Reputation: 1
A little late to the party, but none of these answers, address the simple solution. Use globals and 1. Use a mutex. 2. Do not use a mutex, for shut-down-coming flags. 3. (horrible, not portable, but works great) Do not use mutexs when claiming work for the thread using file rename() on aix/xlc. Rename is automous, and will succed or fail. On success, your thread, has the work. On failure, nope, another thread won. Port this solution to linux, and it will fail, misserably, because rename function is not automous for linux gcc.
Upvotes: 0
Reputation: 5659
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);
}
}
}
Upvotes: 4