Hi,
I'm doing IPC on Linux using boost::interprocess::shared_memory_object
as per the reference (anonymous mutex example).
There's a server process, which creates the shared_memory_object
and writes to it, while holding an interprocess_mutex
wrapped in a scoped_lock
; and a client process which prints whatever the other one has written - in this case, it's an int
.
I ran into a problem: if the server sleeps while holding the mutex, the client process is never able to aquire it and waits forever.
Buggy server loop:
using namespace boost::interprocess;
int n = 0;
while (1) {
std::cerr << "acquiring mutex... ";
{
// "data" is a struct on the shared mem. and contains a mutex and an int
scoped_lock<interprocess_mutex> lock(data->mutex);
data->a = n++;
std::cerr << n << std::endl;
sleep(1);
} // if this bracket is placed before "sleep", everything works
}
Server output:
acquiring mutex... 1
acquiring mutex... 2
acquiring mutex... 3
acquiring mutex... 4
Client loop:
while(1) {
std::cerr << "acquiring mutex... ";
{
scoped_lock<interprocess_mutex> lock(data->mutex);
std::cerr << data->a << std::endl;
}
sleep(1);
}
Client output (waits forever):
acquiring mutex...
The thing is, if I move the bracket to the line before the sleep
call, everything works. Why? I didn't think sleeping with a locked mutex would cause the mutex to be eternally locked.
The only theory I have is that when the kernel wakes up the server process, the scope ends and the mutex is released, but the waiting process isn't given a chance to run. The server then re-acquires the lock... But that doesn't seem to make a lot of sense.
Thanks!