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