Можно ли использовать мьютекс в случае многопроцессорности в 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 у нас есть только безымянные мьютексы, из-за которых они не могут работать между процессами. Нам нужен семафор, чтобы преодолеть это.

В окнах у них есть концепция именованных мьютексов, которая позволяет нам использовать мьютексы в разных процессах.

Другие вопросы по тегам