ero alla ricerca di un mutex denominato in modo che potessi garantire la mutua esclusione per la durata di un processo (assicurandosi che solo un processo in esecuzione per alcune serie di proprietà). Non ne ho trovato uno (sembra che non sia sembrato abbastanza difficile) e quindi ho implementato il mio mutex pseudo chiamato in linux usando un socket di dominio UNIX astratto. Solo un singolo bind() su quel socket avrà successo. L'altra cosa buona è che il SO pulirà il socket del dominio UNIX astratto se il processo muore e quindi non pulisce il socket stesso.Sfortunatamente non sono sicuro che tu possa "aspettare" che questo pseudo mutex diventi disponibile.
Un socket di dominio UNIX astratto è un socket di dominio UNIX il cui nome inizia con un byte null. Attenzione però, credo che l'intero buffer sia usato come nome e quindi vuoi assicurarti di non solo memcpy o strcpy una stringa parziale, o se assicurati di riempire prima l'intero buffer con qualche carattere .
Tutti tranne il primo binding() falliranno con un errno di 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;
}
Grazie, Nick
Dipende da cosa si intende per "multiprocessing". Se si utilizza la definizione stackoverflow, il multiprocessing includerà il multithreading. Se intendi "più processi", hai ragione. –
Vedere http://stackoverflow.com/a/28479697/2189128 – Jeff