I have 3 questions about thread and process communication.
Can the Linux function msgget(), msgsnd(), and msgrcv() be invoked by multiple threads in one process? These functions in different threads are to attempt to access(r/w) one process' message queue. Are all race conditions supposed to be taken care by the system? If not, is there any good method to support threads and send a message to its main thread(process)?
Can semop() function be used to synchronize threads in one process?
There is a shared memory which have the following entities to access.
process
several threads in one process.
Do I have to use semaphore of inter-process level and a semaphore of threads level at the same time? Any simple way to handle this?
A lot of question. :) thanks.
Can the Linux function msgget(), msgsnd(), and msgrcv() be invoked by multiple threads in one process?
You do not need to worry about race conditions, the system will take care of that, there is no race condition with these calls.
can semop() function be used to synchronize threads in one process?
Yes, read more in the documentation
Do I have to use semaphore of inter-process level and a semaphore of threads level?
Any resource which is shared globally among threads or processes is subject to race conditions due to one or more threads or processes trying to access it at the very same time, So you need to synchronize the access to such a shared global resource.
Related
I have 2 threads, the producer thread receives some data over an internet socket, constructs an object and adds it to a queue and the consumer thread pops items from that same queue and does some processing.
Since both threads modify the queue (by enqueuing and dequeuing respectively) I think using a mutex in both threads should be sufficient. Is this a good approach or should I use a semaphore? If so, why?
Either can be made to work. It depends on details of the actual design. How many producer/consumer requests will you allow simultaneously? Is it truly limited to two threads, or will the code spawn others as more requests occur?
I found this short blog interesting. It discusses and compares both the Mutex and Semaphore and may give you some ideas.
"A mutex object allows multiple process threads to access a single shared resource but only one at a time. On the other hand, semaphore
allows multiple process threads to access the finite instance of the
resource until available. In mutex, the lock can be acquired and
released by the same process at a time."
Examples in C
One queue accessed by multiple threads using mutex
Blocking Queue in C++ using semaphores (Not C specific, but concept will be same.)
Do semaphores and mutexes synchronize both threads and processes, or only threads, or only processes?
Edit: my mistake it's C, not shell. Since I programmed through the shell I mistook it. And one more thing: are communication and synchronization the same?
SysV IPC semaphores synchronize between processes.
With POSIX semaphores, you can choose via the pshared argument to sem_init(3) With pshared=1, you can synchronize among all tasks (possibly both threads and processes) that have access to the region of shared memory that you've placed the semaphore at.
Pthread mutexes work on threads.
(Pthreads also has condition variables which are functionally equivalent to semaphores).
The thread versions can have better performance as it's the process that can manage the shared counter, whereas with semaphores, the kernel has to do it.
Synchronization is about determining whether a task can go on or has to wait in coordination with other tasks, and it involves communication, e.g., via incrementing and decrementing semaphores, which are shared among tasks.
I understand that POSIX Message Queues do not require synchronization between different processes. However, how safe are they when being accessed by multiple threads in a single process?
I read this question: Does message queue support Multi-thread? which pertains to SysV Message Queues, and I would assume that POSIX has at least the same support. It seems to imply yes they are thread safe, however:
"Any resource which is shared globally among threads or processes is subject to race conditions"
This would lead me to believe that intra-process synchronization is still required.
In my case in particular both processes that communicate using the message queue implement the 'boss-worker' pattern, and therefore workers can collide into race conditions when attempting to perform operations on the message queues. Would my assumption be correct in stating that access to these queues still requires synchronization within each process?
If you're passing memory addresses of shared memory (either between threads in a process, or memory that's shared between processes) as the contents of your messages, then you still need memory synchronization to access that memory once you read its address out of the message. But you do not need any additional synchronization to perform operations on the message queue itself (aside from destroying it, which you should not do until the last user has finished with it, of course). That's the whole point of having message queues.
The documentation of ØMQ mentions:
Individual ØMQ sockets are not thread safe except in the case where full memory barriers are issued when migrating a socket from one thread to another.
What exactly is meant by "full memory barriers?" Can I have multiple threads send over the same ØMQ socket if I synchronize this with mutexes?
As Ulrich has said, yes you can synchronise access to a single thread using mutexes, but really, why would you want to do that?
It's normally considered good practice to only access a socket from a single thread, and synchronise between threads using messages. Something like this:
Worker thread 1
\
Worker thread 2 - > Control thread -> msg out
/
Worker thread 3
where only the control thread can send messages directly over the socket. Messages from the worker threads would be sent to the control thread over an inproc zmq socket that you would create. The control thread would process just one message at a time which avoids the need for the mutexes, provided the workers have no shared state.
Message based designs are easier to implement and debug, and much easier to maintain than designs using mutexes. If you can change the design to do that, I'd advise doing so.
Acquiring a mutex implies a memory barrier. This basically means that write operations must not be reordered in a way that they cross this operation. Summary: Yes, use a mutex to protect access to the ZMQ socket and you're fine.
I am trying to work out a way to synchronize two processes which share data.
Basically I have two processes linked using shared memory. I need process A to set some data in the shared memory area, then process B to read that data and act on it.
The sequence of events I am looking to have is:
B blocks waiting for data available signal
A writes data
A signals data available
B reads data
B blocks waiting for data not available signal
A signals data not available
All goes back to the beginning.
In other terms, B would block until it got a "1" signal, get the data, then block again until that signal went to "0".
I have managed to emulate it OK using purely shared memory, but either I block using a while loop which consumes 100% of CPU time, or I use a while loop with a nanosleep in it which sometimes misses some of the signals.
I have tried using semaphores, but I can only find a way to wait for a zero, not for a one, and trying to use two semaphores just didn't work. I don't think semaphores are the way to go.
There will be numerous processes all accessing the same shared memory area, and all processes need to be notified when that shared memory has been modified.
It's basically trying to emulate a hardware data and control bus, where events are edge rather than level triggered. It's the transitions between states I am interested in, rather than the states themselves.
So, any ideas or thoughts?
Linux has its own eventfd(2) facility that you can incorporate into your normal poll/select loop. You can pass eventfd file descriptor from process to process through a UNIX socket the usual way, or just inherit it with fork(2).
Edit 0:
After re-reading the question I think one of your options is signals and process groups: start your "listening" processes under the same process group (setpgid(2)), then signal them all with negative pid argument to kill(2) or sigqueue(2). Again, Linux provides signalfd(2) for polling and avoiding slow signal trampolines.
If 2 processes are involved you can use a file , shared memory or even networking to pass the flag or signal. But if the processes are more, there may be some suitable solutions in modifying the kernel. There is one shared memory in your question, right ?! How the signals are passed now ?!
In linux, all POSIX control structures (mutex, conditions, read-write-locks, semaphores) have an option such that they also can be used between processes if they reside in shared memory. For the process that you describe a classic mutex/condition pair seem to fit the job well. Look into the man pages of the ..._init functions for these structures.
Linux has other proper utilities such as "futex" to handle this even more efficiently. But these are probably not the right tools to start with.
1 Single Reader & Single Writer
1 Single Reader & Single Writer
This can be implemented using semaphores.
In posix semaphore api, you have sem_wait() which will wait until value of the semaphore count is zero once it is incremented using sem_post from other process the wait will finish.
In this case you have to use 2 semaphores for synchronization.
process 1 (reader)
sem_wait(sem1);
.......
sem_post(sem2);
process 2(writer)
sem_wait(sem2);
.......
sem_post(sem1);
In this way you can achieve synchronization in shared memory.