18

To jest pytanie do wywiadu.Czy można używać mutex w wieloprocesowym przypadku w systemie Linux/UNIX?

Czy można używać mutex w wieloprocesowym przypadku w systemie Linux/UNIX?

Mój pomysł: Nie, różne procesy mają osobne miejsce w pamięci.

mutex jest używany tylko do wielowątkowości.

Semafor służy do przeprowadzania synchronizacji w trybie wieloprocesowym.

prawda?

Wszelkie komentarze są mile widziane.

dziękuje

+0

Zależy co masz na myśli przez "multiprzetwarzania". Jeśli przejdziesz przez definicję stackoverflow, to wieloprocesowość będzie obejmować wielowątkowość. Jeśli masz na myśli "wiele procesów", masz rację. –

+0

Zobacz http://stackoverflow.com/a/28479697/2189128 – Jeff

Odpowiedz

18
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. 

Inicjalizuj Muteksy są albo wewnątrz procesu lub między procesami, w zależności momencie argumentu przekazywane pośrednio lub bezpośrednio do inicjalizacji tego muteksu. Statycznie przydzielony mutex nie musi być jawnie inicjowany; domyślnie przydzielony statycznie mutex jest inicjowany wszystkimi zerami , a jego zasięg jest ustawiony w ramach procesu wywołującego.

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

również, dla synchronizacji międzyprocesowej, oprócz wymogu alokacji w pamięci współdzielonej, muteksy muszą również używać atrybutu PTHREAD_PROCESS_SHARED, w przeciwnym razie dostęp do muteksu z innego procesu niż jego twórca powoduje niezdefiniowane zachowanie (zobacz: http: // linux.die.net/man/3/pthread_mutexattr_setpshared): "Atrybut współużytkowany przez proces jest ustawiony na PTHREAD_PROCESS_SHARED, aby umożliwić działanie muteksa przez dowolny wątek, który ma dostęp do pamięci, do której jest przydzielony muteks, nawet jeśli muteks jest przydzielana w pamięci współużytkowanej przez wiele procesów " – user1284631

5

Niezupełnie. Wątki POSIX mają koncepcję process-shared attribute, która może być używana do tworzenia muteksów, które mogą być obsługiwane przez wiele procesów.

Możesz umieścić taki muteks w pamięci współdzielonej, aby wszystkie procesy mogły się do niego dostać.

Bez względu na to, czy LINUX to implementuje., Nie jestem pewien, nigdy nie potrzebowałem go używać, ponieważ wydaje się niepotrzebnie skomplikowany.

Po przydatne atrybuty atrybutów, zobacz moją odpowiedź na this question.

0

Tak, ogólnie w Linuksie mamy tylko nienazwane muteksy, dzięki którym nie mogą działać między procesami. Potrzebujemy semafora, żeby to wyjaśnić.

W oknach mają one pojęcie nazwanych muteksów, co pozwala nam używać muteksów w różnych procesach.

+4

Zobacz http://linux.die.net/man/3/pthread_mutexattr_init - LINUX pozwala na muteksy współdzielone przez proces. Niezależnie od tego, czy są one nazwane, czy nie, nie ma znaczenia tutaj, Linux i UNIX mogą udostępniać je bez nazw poprzez dołączanie do wspólnych bloków współdzielonej pamięci. – paxdiablo

+0

Tak, to prawda. Możesz ich używać, dołączając do współdzielonych bloków. :) –

+4

Nie trafna odpowiedź. –

7

Jest całkiem możliwe użycie process-shared mutex.

W rzeczywistości, nowoczesne aplikacje wolą używać wspólnego procesu mutex wraz ze zmienną warunku współdzielonego procesu w semaforze, ponieważ ten drugi jest mniej elastyczny.

Pamiętam, że korzystałem z systemu Red Hat Linux w 2004 r. I w tym czasie obsługiwane były zarówno zmienne związane z procesem, jak i zmienne warunkowe.

2

Szukałem nazwanego mutex, abym mógł zapewnić wzajemne wykluczanie przez cały okres procesu (upewniając się tylko jeden zakonczeniu za pewien zestaw właściwości). Nie znalazłem jednego (wygląda na to, że mogłem nie wyglądać wystarczająco mocno), więc zaimplementowałem swój własny pseudo-mutex w linuxie używając abstrakcyjnego gniazda domeny UNIX. Tylko pojedyncze wiązanie() do tego gniazda zakończy się pomyślnie. Inną dobrą rzeczą jest to, że system operacyjny oczyści abstrakcyjne gniazdo domeny UNIX, jeśli proces zginie, a tym samym nie oczyści samego gniazda.Niestety nie jestem pewien, w jaki sposób można "czekać" na ten pseudo mutex, aby stać się dostępny.

Abstrakcyjne gniazdo domeny UNIX to gniazdo domeny UNIX, którego nazwa rozpoczyna się od pustego bajtu. Uważaj jednak, uważam, że cały bufor jest używany jako nazwa, a więc chcesz się upewnić, że nie tylko zapiszesz w nim ciąg lub wprowadzisz do niego częściowy ciąg, czy też upewnisz się, że najpierw wypełnisz cały bufor pewną postacią .

Wszystkie oprócz pierwszego wiązania() zawiedzie z 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; 
    } 

Dzięki Nick