Можно ли использовать мьютекс в случае многопроцессорности в Linux / UNIX? - PullRequest
21 голосов
/ 22 февраля 2012

Это вопрос интервью.

Можно ли использовать мьютекс в случае многопроцессорной обработки в Linux / UNIX?

Моя идея: нет, разные процессы имеют отдельное пространство памяти.

мьютекс используется только для многопоточности.Семафор

используется для многопроцессорной обработки синхронизации.

верно?

Любые комментарии приветствуются.

спасибо

Ответы [ 5 ]

26 голосов
/ 24 февраля 2012
 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().
8 голосов
/ 22 февраля 2012

Вполне возможно использовать разделяемый процессом мьютекс .

На самом деле современные приложения предпочитают использовать разделяемый мьютекс процесса вместе с переменной общего условия процесса через семафор, потому что последнийменее гибок.

Я помню, как использовал Red Hat Linux в 2004 году, и в то время он поддерживал как взаимные мьютексы процесса, так и переменные условия.

5 голосов
/ 22 февраля 2012

Не совсем. Потоки POSIX имеют концепцию атрибута общего процесса , который можно использовать для создания мьютексов, которыми могут управлять несколько процессов.

Вы можете поместить такой мьютекс в разделяемую память, чтобы все процессы могли получить к нему доступ.

Реализует ли это LINUX. Я не уверен, что мне никогда не приходилось использовать его, поскольку он кажется излишне сложным.

Полезные сведения об атрибутах см. В моем ответе на этот вопрос .

2 голосов
/ 16 мая 2016

Я искал именованный мьютекс, чтобы я мог обеспечить взаимное исключение на время жизни процесса (следя за тем, чтобы только один процесс выполнялся на некоторый набор свойств). Я не нашел его (похоже, я не выглядел достаточно жестко), и поэтому я реализовал свой собственный псевдоним с именем 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;
    }

Спасибо, Ник

0 голосов
/ 22 февраля 2012

Да, в целом в Linux у нас есть только безымянные мьютексы, из-за которых они не могут работать между процессами. Нам нужен семафор, чтобы преодолеть это.

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

...