Можно ли использовать мьютекс в случае многопроцессорности в Linux/UNIX?
Это вопрос интервью.
Можно ли использовать мьютекс в случае многопроцессорности в Linux/UNIX?
Моя идея: нет, разные процессы имеют отдельное пространство памяти.
мьютекс используется только для многопоточности.
Семафор используется для многопроцессорной обработки синхронизации.
право?
Любые комментарии приветствуются.
Спасибо
5 ответов
Mutual exclusion locks (mutexes) prevent multiple threads
from simultaneously executing critical sections of code that
access shared data (that is, mutexes are used to serialize
the execution of threads). All mutexes must be global. A
successful call for a mutex lock by way of mutex_lock()
will cause another thread that is also trying to lock the
same mutex to block until the owner thread unlocks it by way
of mutex_unlock(). Threads within the same process or
within other processes can share mutexes.
Mutexes can synchronize threads within the **same process** or
in ***other processes***. Mutexes can be used to synchronize
threads between processes if the mutexes are allocated in
writable memory and shared among the cooperating processes
(see mmap(2)), and have been initialized for this task.
Инициализация мьютексов является либо внутрипроцессным, либо межпроцессным, в зависимости от аргумента, явно или неявно переданного инициализации этого мьютекса. Статически распределенный мьютекс не требует явной инициализации; по умолчанию статически распределенный мьютекс инициализируется со всеми нулями, и его область действия находится в вызывающем процессе.
For inter-process synchronization, a mutex needs to be allo-
cated in memory shared between these processes. Since the
memory for such a mutex must be allocated dynamically, the
mutex needs to be explicitly initialized using mutex_init().
Вполне возможно использовать разделяемый процессом мьютекс.
Фактически, современные приложения предпочитают использовать разделяемый мьютекс процесса вместе с переменной общего условия процесса через семафор, потому что последний менее гибок.
Я помню, как использовал Red Hat Linux в 2004 году, и в то время он поддерживал как общие мьютексы процесса, так и переменные условия.
Не совсем. Потоки POSIX имеют концепцию общего атрибута процесса, который можно использовать для создания мьютексов, которыми могут управлять несколько процессов.
Вы можете поместить такой мьютекс в общую память, чтобы все процессы могли получить к нему доступ.
Реализует ли это LINUX. Я не уверен, что мне никогда не приходилось его использовать, поскольку это кажется излишне сложным.
Для получения полезной информации об атрибутах см. Мой ответ на этот вопрос.
Я искал именованный мьютекс, чтобы я мог обеспечить взаимное исключение на весь срок жизни процесса (следя за тем, чтобы на один набор свойств работал только один процесс). Я не нашел ни одного (похоже, я не выглядел достаточно сложно), и поэтому я реализовал свой собственный псевдоним с именем mutex в linux, используя абстрактный сокет домена UNIX. Только одна привязка () к этому сокету будет успешной. Другая приятная вещь заключается в том, что ОС очистит абстрактный сокет домена UNIX, если процесс умрет и, следовательно, не очистит сам сокет. К сожалению, я не уверен, что вы сможете "подождать", пока этот псевдо-мьютекс станет доступным.
Абстрактный сокет домена UNIX - это сокет домена UNIX, имя которого начинается с нулевого байта. Тем не менее, я считаю, что в качестве имени используется весь буфер, и поэтому вы хотите убедиться, что вы не просто запишите в него memcpy или strcpy частичную строку, или если вы действительно убедитесь, что сначала заполнили весь буфер некоторым символом,
Все, кроме первого bind() завершатся с ошибкой EADDRINUSE.
// Create an abstract socket to use as a mutex.
int err;
int mutex_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (mutex_sock == -1)
{
err = errno;
printf("main, failed creating mutex socket: %s\n",
get_error_string(errno, error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed creating mutex socket: "
"%s", get_error_string(errno, error_string,
sizeof(error_string)));
errno = err;
goto done;
}
// Bind to abstract socket. We use this as a sort of named mutex.
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path + 1, socket_name, sizeof(addr.sun_path) - 2);
result = bind(mutex_sock, (struct sockaddr*) &addr, sizeof(addr));
if (result == -1)
{
err = errno;
if (errno == EADDRINUSE)
{
printf("main, failed bind to mutex socket: %s. "
"Another instance must be running.\n",
get_error_string(errno,
error_string, sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: "
"%s. "
"Another instance must be running.",
get_error_string(errno,
error_string, sizeof(error_string)));
}
else
{
printf("main, failed bind to mutex socket: %s\n",
get_error_string(errno, error_string,
sizeof(error_string)));
log_event(LOG_LEVEL_ERROR, "main, failed bind to mutex socket: %s",
get_error_string(errno, error_string,
sizeof(error_string)));
}
errno = err;
goto done;
}
Спасибо ник
Да, в целом в Linux у нас есть только безымянные мьютексы, из-за которых они не могут работать между процессами. Нам нужен семафор, чтобы преодолеть это.
В окнах у них есть концепция именованных мьютексов, которая позволяет нам использовать мьютексы в разных процессах.