Я делаю IPC на Linux , используя boost::interprocess::shared_memory_object
согласно ссылку (пример анонимного мьютекса).
Существует серверный процесс, который создает shared_memory_object
и записывает в него, удерживая interprocess_mutex
в scoped_lock
; и клиентский процесс, который печатает все, что написал другой - в данном случае это int
.
Я столкнулся с проблемой: если сервер спит, удерживая мьютекс, клиентский процесс никогда не сможет его захватить и будет ждать вечно.
Багги сервер цикл:
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
}
Сервер Вывод:
acquiring mutex... 1
acquiring mutex... 2
acquiring mutex... 3
acquiring mutex... 4
Клиент цикл:
while(1) {
std::cerr << "acquiring mutex... ";
{
scoped_lock<interprocess_mutex> lock(data->mutex);
std::cerr << data->a << std::endl;
}
sleep(1);
}
Клиент вывод (ждет вечно):
acquiring mutex...
Дело в том, что если я передвину скобку на строку перед вызовом sleep
, все будет работать. Зачем? Я не думал, что сон с заблокированным мьютексом навсегда заблокирует мьютекс.
Единственная теория, которая у меня есть, состоит в том, что, когда ядро запускает процесс сервера, область действия заканчивается, и мьютекс освобождается, но процессу ожидания не дают возможности для запуска. Затем сервер вновь получает блокировку ... Но, похоже, это не имеет большого смысла.
Спасибо!