18

Đây là câu hỏi phỏng vấn.Có thể sử dụng mutex trong trường hợp đa xử lý trên Linux/UNIX không?

Có thể sử dụng mutex trong trường hợp đa xử lý trên Linux/UNIX không?

Ý tưởng của tôi: Không, các quy trình khác nhau có không gian bộ nhớ riêng biệt.

mutex chỉ được sử dụng để đa luồng.

semaphore được sử dụng để đa xử lý để thực hiện đồng bộ hóa.

phải không?

Mọi nhận xét đều được chào đón.

cảm ơn

+0

Phụ thuộc vào những gì bạn có nghĩa là bởi "đa". Nếu bạn đi theo định nghĩa stackoverflow, sau đó đa xử lý sẽ bao gồm đa luồng. Nếu bạn có nghĩa là "nhiều quá trình", thì bạn đã đúng. –

+0

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

Trả lời

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. 

Initialize Mutexes là một trong hai nội quy trình hay inter-process, tùy thuộc khi lập luận thông qua ngầm hay rõ ràng để các khởi của mutex đó. Một mutex phân bổ tĩnh không cần phải được khởi tạo rõ ràng; theo mặc định, mutex được phân bổ tĩnh được khởi tạo với tất cả các sốvà phạm vi của nó được đặt trong quá trình gọi.

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

Ngoài ra, đối với quá trình đồng bộ hóa, ngoài yêu cầu được cấp phát trong bộ nhớ chia sẻ, các mutex cũng phải sử dụng thuộc tính PTHREAD_PROCESS_SHARED, nếu không truy cập vào mutex từ quá trình khác với kết quả tạo ra trong hành vi chưa xác định (xem điều này: http: // linux.die.net/man/3/pthread_mutexattr_setpshared): "Thuộc tính quá trình chia sẻ được đặt thành PTHREAD_PROCESS_SHARED để cho phép một mutex được vận hành theo bất kỳ chuỗi nào có quyền truy cập vào bộ nhớ trong đó mutex được cấp phát, ngay cả khi mutex được cấp phát trong bộ nhớ được chia sẻ bởi nhiều quá trình " – user1284631

5

Không hoàn toàn. Các chủ đề POSIX có khái niệm về process-shared attribute có thể được sử dụng để tạo các mutex có thể được vận hành bởi nhiều quy trình.

Bạn có thể đặt một mutex như vậy trong bộ nhớ dùng chung để có thể nhận được nhiều quy trình tại đó.

Liệu LINUX có thực hiện điều này không, tôi không chắc chắn, tôi chưa bao giờ có nhu cầu sử dụng nó vì nó có vẻ phức tạp không cần thiết.

Để biết các precis hữu ích của thuộc tính, hãy xem câu trả lời của tôi cho this question.

0

Có, nói chung trong Linux, chúng tôi chỉ có các mutex chưa được đặt tên do chúng không thể hoạt động giữa các quá trình. Chúng ta cần một semaphore để vượt qua điều đó.

Trong cửa sổ, chúng có khái niệm về các mutex được đặt tên cho phép chúng tôi sử dụng các mutex trên các quy trình.

+4

Xem http://linux.die.net/man/3/pthread_mutexattr_init - LINUX cho phép các mutex được chia sẻ theo quy trình. Cho dù chúng được đặt tên hay không là không có liên quan ở đây, Linux và UNIX có thể chia sẻ chúng mà không có tên bằng cách gắn vào các khối bộ nhớ chia sẻ chung. – paxdiablo

+0

Vâng, đó là chính xác. Bạn có thể sử dụng chúng bằng cách đính kèm vào khối chia sẻ. :) –

+4

Câu trả lời không chính xác. –

7

Có thể sử dụng process-shared mutex.

Thực tế, các ứng dụng hiện đại thích sử dụng quá trình chia sẻ mutex cùng với biến điều kiện được chia sẻ quá trình trên semaphore vì sau này ít linh hoạt hơn.

Tôi nhớ đã sử dụng Red Hat Linux vào năm 2004 và tại thời điểm đó, nó hỗ trợ cả hai biến chia sẻ quy trình và biến điều kiện.

2

Tôi đang tìm kiếm một mutex có tên để tôi có thể đảm bảo loại trừ lẫn nhau trong suốt quá trình (đảm bảo chỉ có một quy trình chạy trên một số thuộc tính). Tôi đã không tìm thấy một (có vẻ như tôi có thể đã không nhìn cứng đủ) và vì vậy tôi thực hiện giả của tôi tên là mutex trong linux bằng cách sử dụng một ổ cắm miền UNIX trừu tượng. Chỉ một bind() duy nhất cho socket đó sẽ thành công. Điều tốt đẹp khác là hệ điều hành sẽ dọn sạch ổ cắm miền UNIX trừu tượng nếu quá trình chết và do đó không dọn sạch ổ cắm.Thật không may tôi không chắc chắn về bất kỳ cách nào để bạn "chờ đợi" trên giả này mutex để trở thành có sẵn.

Ổ cắm miền UNIX trừu tượng là một ổ cắm miền UNIX có tên bắt đầu bằng một byte rỗng. Hãy cẩn thận, tôi tin rằng toàn bộ bộ đệm được sử dụng như tên và do đó bạn muốn đảm bảo rằng bạn không chỉ ghi nhớ hoặc xâu chuỗi một phần vào nó, hoặc nếu bạn chắc chắn rằng bạn đầu tiên điền vào toàn bộ bộ đệm với một số ký tự .

Tất cả trừ liên kết đầu tiên() sẽ thất bại với lỗi không đúng 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; 
    } 

Cảm ơn, Nick

Các vấn đề liên quan