Est-il possible d'utiliser mutex dans multiprocessing case sous Linux/UNIX?
il s'agit d'une question d'entrevue.
est-il possible d'utiliser mutex dans multiprocessing case sous Linux/UNIX ?
Mon idée: Non, différents processus ont un espace mémoire séparé.
mutex n'est utilisé que pour le multithreading.
sémaphore est utilisé pour le multitraitement de faire la synchronisation.
droit ?
tout commentaire est bienvenu.
merci
5 réponses
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 intra-processus ou inter-processus, selon sur l'argument passé implicitement ou explicitement à la initialisation du mutex. Un mutex statiquement alloué n'a pas besoin d'être explicitement initialisée; par défaut, un le mutex attribué statiquement est initialisé avec tous les zéros et sa portée est définie pour être dans le processus d'appel.
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 partagé par les processus.
en fait, les applications modernes préfèrent utiliser un mutex partagé avec une variable de condition partagée plutôt qu'un sémaphore parce que ce dernier est moins flexible.
je me souviens avoir utilisé Red Hat Linux en 2004 et à cette époque il supportait à la fois les Mutex de processus partagés et les variables de condition.
Pas tout à fait. POSIX threads a un concept de attribut de processus partagé, qui peut être utilisé pour créer des mutex qui peuvent être exploitées par de multiples processus.
Vous pouvez mettre un tel mutex dans la mémoire partagée, de sorte que plusieurs processus peuvent tous.
si LINUX implémente cela. Je ne suis pas sûr, je n'ai jamais eu besoin de l'utiliser car il semble inutilement complexe.
pour un précis utile d'attributs, voir ma réponse à ce question.
je cherchais un mutex nommé afin de pouvoir assurer l'exclusion mutuelle pendant toute la durée d'un processus (en m'assurant qu'il n'y ait qu'un seul processus par ensemble de propriétés). Je n'en ai pas trouvé (on dirait que je n'ai pas assez cherché) et j'ai donc implémenté mon propre pseudo appelé mutex sous linux en utilisant une socket de domaine UNIX abstraite. Seule une seule connexion() à cette socket réussira. L'autre chose intéressante est que le système d'exploitation nettoiera la socket de domaine unix abstraite si le processus meurt et donc ne nettoie pas la prise elle-même. Malheureusement, je ne suis pas sûr d'un moyen pour vous d '"attendre" sur ce mutex pseudo pour devenir disponible.
une socket de domaine UNIX abstraite est une socket de domaine UNIX dont le nom commence par un octet nul. Attention cependant, je crois que tout le buffer est utilisé comme nom et donc vous voulez vous assurer que vous ne vous contentez pas de memcpy ou strcpy une chaîne partielle en elle, ou si vous vous assurez que vous remplissez d'abord tout le buffer avec certains caractère.
Tous les mais la première bind() échoue avec errno 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 sans nom pour lesquels ils ne peuvent pas fonctionner entre les processus. Il nous faut un sémaphore pour surmonter ça.
dans windows, ils ont un concept de mutex nommés qui nous permet d'utiliser des Mutex à travers les processus.