Reputation: 13464
I am having a C project which has 2 threads, main_thread
and worker_thread
. Below pseudocode explains about it.
TASK g_task[MAX_TASK];
worker_thread()
{
do {
listen_for_task on g_task
do_task(0);
} while(0);
}
int post_task(msg)
{
post on g_task
/* I am planning for a kind of file descriptor to return from here */
/* on which main thread polls along with sock_fd */
return fd;
}
main_thread()
{
int sock_fd;
/* sock_fd listens on well known TCP port for msgs from clients */
/* Using epoll */
ev.events = EPOLIN;
ev.data.fd = sock_fd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, sock_fd, &ev);
do {
nfs = epoll_wait(...)
if (nfs > 0) {
/* I read the msg from from sock_fd and post to g_task */
post_task(msg)
}
} while (0);
}
On main_thread
I am waiting on a tcp socket for msgs from various clients. I am processing and posting the work to be done to another thread worker_thread
.
Now I want the worker_thread
to notify main_thread
after finishing each task posted to it. I am expecting the event should come to a new file descriptor. That means I am expecting post_task
should return a new fd
which I can add to epollfd
. And worker_thread
should wakeup it.
Any suggestion for achieving this is ?
Upvotes: 0
Views: 129
Reputation: 52549
Since you mention using epoll, you must be using Linux. Which means you can use eventfd()
.
Basically, your post_task
function creates a new eventfd descriptor for each thread and the main thread monitors it for readability in epoll. The thread then writes a 64 bit integer to its descriptor when it's done. The main thread then wakes from epoll, sees the event is readable, reads a 64 bit integer from it, and does whatever it needs to do now that it knows the associated thread is done with a task. (On non-linux systems you can get a similar effect using pipe()
; I've written code with an event creation function that switches between the two depending on what OS is being targeted)
If you need to pass more information than just a "I'm done" status, I like using a Unix domain datagram socket created with socketpair()
and reading/writing structs with all the needed data. If you include a thread id, all threads can even share the same socket.
Upvotes: 1