web-dev-qa-db-fra.com

Est-il possible d'utiliser mutex en multitraitement sous Linux/UNIX?

Ceci est une question d'entrevue. 

Est-il possible d'utiliser mutex en multitraitement sous Linux/UNIX? 

Mon idée: Non, différents processus ont un espace mémoire séparé. 

le mutex n'est utilisé que pour le multithreading. 

le sémaphore est utilisé pour le multitraitement afin d'effectuer la synchronisation. 

droite ? 

Tous les commentaires sont les bienvenus. 

merci

21
user1002288
 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.

Initialiser Les mutex sont soit intra-processus ou inter-processus, selon sur l'argument passé implicitement ou explicitement à la initialisation de ce mutex. Un mutex alloué statiquement n'a pas besoin d'être explicitement initialisé; par défaut, un Le mutex alloué statiquement est initialisé avec tous les zéros et sa portée est définie pour être dans le processus appelant.

 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().
23
laksbv

Il est tout à fait possible d’utiliser un mutex process-shared .

En fait, les applications modernes préfèrent utiliser un mutex de processus partagé avec une variable de condition de processus partagée plutôt qu'un sémaphore, car ce dernier est moins flexible.

Je me souviens d'avoir utilisé Red Hat Linux en 2004 et, à cette époque, il prenait en charge les mutex de processus partagés et les variables de condition.

8
Maxim Egorushkin

Pas assez. Les threads POSIX ont un concept d'attribut process-shared qui peut être utilisé pour créer des mutex pouvant être exploités par plusieurs processus.

Vous pouvez mettre un tel mutex en mémoire partagée afin que plusieurs processus puissent y accéder.

Je ne sais pas si LINUX le met en œuvre. Je n’ai jamais eu besoin de l’utiliser, car cela semble inutilement complexe.

Pour une précision utile sur les attributs, voir ma réponse à cette question .

5
paxdiablo

Je recherchais un mutex nommé afin de pouvoir assurer une exclusion mutuelle pendant la durée d'un processus (en m'assurant qu'un seul processus s'exécute par un ensemble de propriétés). Je n'en ai pas trouvé (j'ai l'air de ne pas avoir assez cherché) et j'ai donc implémenté mon propre pseudo mutex nommé sous Linux en utilisant un socket de domaine UNIX abstrait. Un seul lien () à ce socket réussira. L’autre atout, c’est que le système d’exploitation nettoie le socket de domaine abstrait UNIX si le processus s’arrête et ne nettoie donc pas le socket lui-même. Malheureusement, je ne suis pas sûr que vous puissiez "attendre" que ce pseudo mutex soit disponible.

Un socket de domaine UNIX abstrait est un socket de domaine UNIX dont le nom commence par un octet nul. Attention cependant, je crois que le tampon entier est utilisé comme nom et vous voulez donc vous assurer que vous ne mémorisez pas ou ne strcpiez pas une chaîne partielle dans celle-ci, ou si vous vous assurez d’abord remplir tout le tampon avec un caractère .

Tout sauf le premier bind () échouera avec le code d'erreur 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;
    }

Merci, Nick

2
nickdu

Oui, en général sous Linux, nous n’avons que des mutex non nommés, ce qui les empêche de fonctionner entre les processus. Nous avons besoin d'un sémaphore pour surmonter cela.

Dans Windows, ils ont un concept de mutex nommé qui nous permet d’utiliser des mutex d’un processus à l’autre. 

0
Gargi Srinivas