Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C: How to make threads communicate with each other?

Interesting that this seems to be a basic question, and yet I couldn't find any example of it for the C language (in SO, I found only for Python, C# and C++).

The point is: as a Qt programmer, when I need to make some data to be transmitted between different threads, I start a signal-slot connection between then and use the emit signal mechanism to do the work.

But now I'm working in a C application for Embedded Linux where I need to do a similar work, but I don't have Qt's mechanism available. The question is: how can I make two or more threads communicate with each other in C in a manner similar to that of Qt with signals and slots?

I know that one of the ways to share data is with global variables with changes protected by mutexes. But even then I would probably be unable to do the system in a asynchronous way: I would have to have a loop that would constantly check if the variable has changed or not. But what if I want to execute a specific method of a thread just after another one finished some work (so, in an asynchronous way)? Then it seems such way fails.

Note: although I'm using Embedded Linux and, therefore, mentioning some options that would take POSIX functions and other "Linux-related ways" would be helpful, it would still be better for the community if more time is given to solutions that are not based strictly to one specific platform (if that is possible).

like image 621
Momergil Avatar asked Sep 16 '14 19:09

Momergil


2 Answers

Read a good tutorial on pthreads. You want to know more about condition variables to be used with mutexes.

Condition variables and mutexes should probably be enough for your needs.

You could also use most traditional inter-process communication mechanisms between threads, e.g. a pipe(7) (probably with poll(2)...). So read Advanced Linux Programming and study syscalls(2) and pthreads(7)

Avoid using signal(7)-s between threads and be aware of signal-safety(7). See however signalfd(2), eventfd(2), userfaultfd(2) (you might cleverly handle SIGSEGV with it) and take inspiration from the approach suggested by Calling Qt functions from Unix signal handler.

Observe a running multi-threaded Linux process with strace(1), ltrace(1), gdb(1). You'll understand that several pthreads(7) primitives are using futex(7).

Both GNU glibc and musl-libc are open source and implement the pthreads specification (and Glib, GTK, Qt or POCO are built above them). I invite you to study their source code.

like image 192
Basile Starynkevitch Avatar answered Sep 29 '22 23:09

Basile Starynkevitch


One way is to use message passing between threads via asynchronous queues. This way you can avoid using shared data between threads and only the queues need to be thread-safe.

Asynchronous queues can be implemented using different synchronisation primitives:

  • Pipes or sockets.
  • Queues protected with a mutex and a condition variable.
  • Non-blocking or lock-free queues.
like image 20
Maxim Egorushkin Avatar answered Sep 29 '22 22:09

Maxim Egorushkin