2010-10-28 17 views

Trả lời

47

Một mutex là đối tượng loại trừ lẫn nhau, tương tự cho semaphore nhưng chỉ cho phép một tủ khóa cùng một lúc và hạn chế quyền sở hữu có thể nghiêm ngặt hơn semaphore.

Nó có thể được coi là tương đương với một semaphore đếm bình thường (với số đếm một) và yêu cầu rằng nó chỉ có thể được giải phóng bởi cùng một sợi khóa nó (a).

Một semaphore, mặt khác, có một số tùy ý và có thể bị khóa bởi nhiều tủ khóa cùng một lúc. Và nó có thể không có một yêu cầu rằng nó được phát hành bởi cùng một thread tuyên bố nó (nhưng, nếu không, bạn phải cẩn thận theo dõi những người hiện đang có trách nhiệm cho nó, giống như phân bổ bộ nhớ).

Vì vậy, nếu bạn có một số trường hợp tài nguyên (nói ba ổ băng), bạn có thể sử dụng semaphore với tổng số 3. Lưu ý rằng điều này không cho bạn biết ổ đĩa băng nào bạn có, chỉ là bạn có một số lượng nhất định.

Cũng với các ẩn dụ, có thể có một tủ khóa để khóa nhiều phiên bản của tài nguyên, chẳng hạn như đối với bản sao băng từ thành băng. Nếu bạn có một tài nguyên (nói một vị trí bộ nhớ mà bạn không muốn bị hỏng), một mutex phù hợp hơn.

hoạt động tương đương là:

Counting semaphore   Mutual exclusion semaphore 
-------------------------- -------------------------- 
    Claim/decrease (P)     Lock 
    Release/increase (V)    Unlock 

Ngoài: trong trường hợp bạn đã bao giờ tự hỏi tại các chữ cái kỳ lạ sử dụng để tuyên bố và phát hành Cột, đó là vì các nhà phát minh là Hà Lan. Probeer verlagen có nghĩa là để thử và giảm trong khi verhogen có nghĩa là để tăng lên.


(a) ... hoặc nó có thể được coi như là một cái gì đó hoàn toàn khác biệt với một semaphore, có thể được an toàn hơn cho họ sử dụng gần như luôn luôn khác nhau.

+0

Được rồi, tôi đã gặp nhị phân semaphore quá. Khi nào chúng ta cần phải đi cho semaphore nhị phân và khi nào chúng ta nên sử dụng mutex? –

+0

Khái niệm, một semaphore nhị phân _is_ một mutex, và nó tương đương với một semaphore bình thường với một số.Có thể có sự khác biệt trong _implementations_ của khái niệm như hiệu quả hoặc quyền sở hữu tài nguyên (có thể được phát hành bởi một người nào đó không phải là người xác nhận quyền sở hữu, mà tôi không đồng ý với BTW - tài nguyên chỉ có thể giải thích được bằng chuỗi). – paxdiablo

+1

Một khác biệt triển khai tiềm năng là mutex đệ quy. Vì chỉ có một tài nguyên, một chuỗi đơn lẻ có thể được phép khóa nhiều lần (miễn là nó giải phóng nó nhiều lần). Điều này không dễ dàng như vậy với một tài nguyên nhiều cá thể vì bạn có thể không biết liệu luồng có muốn yêu cầu cá thể _another_ hay cá thể _same_ một lần nữa hay không. – paxdiablo

1

Như đã được chỉ ra, một semaphore với một số của một là giống như một 'nhị phân' semaphore đó là điều tương tự như một mutex.

Những điều chính tôi đã nhìn thấy semaphores với một số lớn hơn một được sử dụng cho là tình hình sản xuất/người tiêu dùng trong đó bạn có một hàng đợi của một kích thước cố định nhất định.

Bạn có hai ẩn dụ sau đó. Semaphore đầu tiên ban đầu được thiết lập là số lượng các mục trong hàng đợi và semaphore thứ hai được thiết lập để 0. Các nhà sản xuất thực hiện một hoạt động P trên semaphore đầu tiên, thêm vào hàng đợi. và thực hiện thao tác V trên giây. Người tiêu dùng thực hiện thao tác P trên semaphore thứ hai, loại bỏ khỏi hàng đợi và sau đó thực hiện thao tác V trên đầu tiên.

Bằng cách này, nhà sản xuất bị chặn bất cứ khi nào nó lấp đầy hàng đợi và người tiêu dùng bị chặn bất cứ khi nào hàng đợi trống.

12

Trong khi @opaxdiablo câu trả lời là hoàn toàn chính xác, tôi muốn chỉ ra rằng kịch bản sử dụng của cả hai điều là khá khác nhau. Các mutex được sử dụng để bảo vệ các phần của mã chạy đồng thời, semaphores được sử dụng cho một thread để báo hiệu một thread để chạy.

/* Task 1 */ 
pthread_mutex_lock(mutex_thing); 
    // Safely use shared resource 
pthread_mutex_unlock(mutex_thing); 



/* Task 2 */ 
pthread_mutex_lock(mutex_thing); 
    // Safely use shared resource 
pthread_mutex_lock(mutex_thing); 

Kịch bản semaphore là khác nhau:

/* Task 1 - Producer */ 
sema_post(&sem); // Send the signal 

/* Task 2 - Consumer */ 
sema_wait(&sem); // Wait for signal 

Xem http://www.netrino.com/node/202 cho lời giải thích thêm

+2

Bạn nói đúng. Ngay cả khi bạn đang sử dụng một semaphore với một số của một, bạn đang ngụ ý một cái gì đó về những gì bạn đang làm hơn nếu bạn sử dụng một mutex. – Omnifarious

+0

Tôi không chắc chắn rằng tôi đồng ý với điều đó, mặc dù tôi không _disagree_ nên kịch liệt rằng tôi sẽ downvote bạn :-) Bạn nói rằng mô hình sử dụng của semaphores là để thông báo cho chủ đề nhưng đó là chính xác những gì mutexes làm khi có thread khác chờ đợi trên đó, và chính xác những gì semaphores _don't_ khi không có chủ đề trong 'sema_wait' :-) Theo ý kiến ​​của tôi, họ đang _both_ về tài nguyên và thông báo trao cho chủ đề khác là một tác dụng phụ (rất quan trọng, hiệu suất- khôn ngoan) của bảo vệ. – paxdiablo

+0

'Bạn nói rằng mẫu sử dụng của các semaphores là để thông báo cho các chủ đề ' Một điểm về việc thông báo chuỗi. Bạn có thể gọi 'sem_post' từ trình xử lý tín hiệu một cách an toàn (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html) nhưng không được khuyên dùng để gọi' pthread_mutex_lock' và 'pthread_mutex_unlock' từ trình xử lý tín hiệu (http://manpages.ubuntu.com/manpages/lucid/man3/pthread_mutex_init.3.html#contenttoc4) –

8

Xem "The Toilet Ví dụ" - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm:

Mutex:

Chìa khóa cho nhà vệ sinh. Một người có thể có chìa khóa - chiếm nhà vệ sinh - vào thời điểm đó. Khi kết thúc, người đó đưa (giải phóng) chìa khóa cho người tiếp theo trong hàng đợi.

Chính thức: "Mutexes thường được sử dụng để nối tiếp truy cập vào một phần của mã tái nhập mà không thể thực hiện đồng thời bởi nhiều hơn một luồng. Một đối tượng mutex chỉ cho phép một luồng vào một phần được kiểm soát, buộc các luồng khác cố gắng để có quyền truy cập vào phần đó để chờ cho đến khi chuỗi đầu tiên đã thoát khỏi phần đó. " Ref: Symbian Developer Library

(A mutex thực sự là một semaphore với giá trị 1.)

Semaphore:

là số lượng các phím vệ sinh giống hệt nhau miễn phí. Ví dụ, chúng ta có bốn nhà vệ sinh với khóa và khóa giống hệt nhau. Số đếm semaphore - số lượng các phím - được đặt thành 4 lúc bắt đầu (tất cả bốn nhà vệ sinh là miễn phí), sau đó giá trị đếm được giảm đi khi mọi người đang đến. Nếu tất cả các nhà vệ sinh đầy, nghĩa là. không có phím miễn phí còn lại, số đếm semaphore là 0. Bây giờ, khi eq. một người rời khỏi nhà vệ sinh, semaphore được tăng lên 1 (một chìa khóa miễn phí), và trao cho người tiếp theo trong hàng đợi.

Chính thức: "Một semaphore hạn chế số lượng người dùng đồng thời của tài nguyên được chia sẻ tối đa số. Chủ đề có thể yêu cầu quyền truy cập vào tài nguyên (giảm semaphore) và có thể báo hiệu rằng họ đã hoàn thành bằng tài nguyên (tăng dần semaphore). " Ref: Symbian Thư viện phát triển

35

Điều rất quan trọng để hiểu rằng một mutex không một semaphore với số 1!

Đây là lý do có những thứ như các ẩn dụ nhị phân (thực sự là các ẩn dụ có số đếm 1).

Sự khác biệt giữa một Mutex và Binary-Semaphore là nguyên tắc của quyền sở hữu:

Một mutex được mua lại bởi một công việc và do đó cũng phải được phát hành bởi cùng một công việc. Điều này làm cho nó có thể sửa chữa một số vấn đề với semaphores nhị phân (phát hành chính thức, bế tắc bế tắc và đảo ngược ưu tiên).

Caveat: Tôi đã viết "làm cho nó có thể", nếu và làm thế nào những vấn đề này được cố định là lên đến việc thực hiện hệ điều hành.

Bởi vì mutex phải được phát hành bởi cùng một nhiệm vụ, nó không phải là rất tốt cho đồng bộ hóa các nhiệm vụ. Nhưng nếu kết hợp với các biến điều kiện bạn sẽ nhận được các khối xây dựng rất mạnh mẽ để xây dựng tất cả các loại nguyên thủy ipc.

Vì vậy, đề nghị của tôi là: nếu bạn đã thực hiện sạch mutexes và biến điều kiện (như với POSIX pthreads) sử dụng các.

Sử dụng Cột chỉ khi chúng phù hợp chính xác cho vấn đề bạn đang cố gắng để giải quyết, không nên cố gắng để xây dựng nguyên thủy khác (ví dụ rw-ổ khóa ra khỏi Cột, sử dụng mutexes và các biến điều kiện cho các)

Có là rất nhiều mutexes và semaphores hiểu lầm. Lời giải thích tốt nhất mà tôi tìm thấy cho đến nay là 3-Phần bài viết này:

Mutex vs. Semaphores – Part 1: Semaphores

Mutex vs. Semaphores – Part 2: The Mutex

Mutex vs. Semaphores – Part 3 (final part): Mutual Exclusion Problems

+0

Các url đến trang web này chứa các ký tự funky và không hoạt động do đó ... Tôi đang làm việc với nó –

+0

Cố định các ký tự unicode trong urs, các liên kết hiện hoạt động. –

67

Dưới đây là cách tôi nhớ khi sử dụng những gì -

Semaphore : Sử dụng một semaphore khi bạn (thread) muốn ngủ cho đến khi một số thread khác cho bạn biết để thức dậy. Semaphore 'down' xảy ra trong một chủ đề (nhà sản xuất) và semaphore 'up' (cho cùng một semaphore) xảy ra trong một chủ đề khác (tiêu dùng) ví dụ: Trong vấn đề người tiêu dùng sản xuất, nhà sản xuất muốn ngủ đến ít nhất một vùng đệm trống - chỉ chuỗi tiêu thụ mới có thể biết khi nào một vùng đệm trống.

Mutex: Sử dụng mutex khi bạn (thread) muốn thực thi mã không nên được thực hiện bởi bất kỳ chuỗi nào khác cùng một lúc. Mutex 'down' xảy ra trong một thread và mutex 'up' phải xảy ra trong cùng một chuỗi sau này. ví dụ: Nếu bạn đang xóa một nút khỏi danh sách được liên kết toàn cục, bạn không muốn một chuỗi khác ẩn xung quanh bằng con trỏ trong khi bạn đang xóa nút. Khi bạn có được một mutex và đang bận xóa một node, nếu một thread khác cố gắng để có được cùng một mutex, nó sẽ được đưa vào trạng thái ngủ cho đến khi bạn giải phóng mutex.

Spinlock: Sử dụng spinlock khi bạn thực sự muốn sử dụng mutex nhưng chuỗi của bạn không được phép ngủ. ví dụ: Một trình xử lý ngắt trong hạt nhân OS không bao giờ được ngủ. Nếu nó làm hệ thống sẽ đóng băng/sụp đổ. Nếu bạn cần chèn một nút vào danh sách được liên kết được chia sẻ trên toàn cầu từ trình xử lý ngắt, hãy lấy một nút xoay - nút chèn - phát hành spinlock.

+0

để thêm vào: semaphores và mutex là hai cách để cung cấp đồng bộ hóa. semaphore, có thể liên quan nhiều hơn đến báo hiệu (ví dụ: kịch bản sản xuất và vấn đề người tiêu dùng), và mutex, có thể liên quan nhiều hơn đến việc cho phép truy cập vào cùng một lúc (một số yêu cầu truy cập tài nguyên được chia sẻ, nhưng chỉ có một yêu cầu được cấp tại một thời điểm). [bài viết hay: http://www.geeksforgeeks.org/mutex-vs-semaphore/] – parasrish

7

Cố gắng không phát ra âm thanh, nhưng không thể giúp bản thân.

Câu hỏi của bạn phải là sự khác biệt giữa mutex và semaphores là gì? Và để có câu hỏi chính xác hơn, 'mối quan hệ giữa mutex và semaphores là gì?'

(. Tôi sẽ có thêm câu hỏi đó nhưng tôi trăm% chắc chắn một số người điều hành quá hăng hái sẽ đóng nó như trùng lặp mà không hiểu sự khác biệt giữa sự khác biệt và mối quan hệ)

Trong thuật ngữ đối tượng chúng ta có thể nhận xét rằng:

quan sát.1 Semaphore chứa mutex

quan sát.2 Mutex không phải là semaphore và semaphore không phải là mutex.

Có một số semaphores sẽ hoạt động như thể chúng là mutex, được gọi là semaphores nhị phân, nhưng chúng là freaking NOT mutex.

Có một thành phần đặc biệt được gọi là báo hiệu (posix sử dụng điều kiện_variable cho tên đó), cần thiết để thực hiện một Semaphore ra khỏi mutex. Hãy coi nó như một nguồn thông báo. Nếu hai hoặc nhiều luồng được đăng ký với cùng một nguồn thông báo, thì có thể gửi tin nhắn đó đến MỘT hoặc TẤT CẢ, để đánh thức.

Có thể có một hoặc nhiều quầy được liên kết với các ẩn dụ, được bảo vệ bởi mutex. Kịch bản đơn giản nhất cho semaphore, có một bộ đếm đơn lẻ có thể là 0 hoặc 1.

Đây là nơi mà sự nhầm lẫn đổ vào như mưa gió mùa.

Một semaphore với bộ đếm có thể là 0 hoặc 1 KHÔNG phải là mutex.

Mutex có hai trạng thái (0,1) và một quyền sở hữu (tác vụ). Semaphore có một mutex, một số quầy và một biến điều kiện.

Bây giờ, hãy sử dụng trí tưởng tượng của bạn và mọi kết hợp sử dụng bộ đếm và khi nào thì tín hiệu có thể tạo ra một kiểu Semaphore.

  1. Độc truy cập có giá trị 0 hoặc 1 và tín hiệu khi giá trị đi vào 1 AND sau đó mở ra một trong những anh chàng chờ đợi trên tín hiệu == semaphore nhị phân

  2. truy cập đơn có giá trị từ 0 đến N và tín hiệu khi giá trị nhỏ hơn N và khóa/chờ khi giá trị là N == Đếm semaphore

  3. Bộ đếm đơn có giá trị 0 đến N và báo hiệu khi giá trị đến N và khóa/chờ khi giá trị nhỏ hơn N == Barrier semaphore (tốt nếu họ không gọi nó, thì họ nên.)

Bây giờ cho câu hỏi của bạn, khi nào nên sử dụng cái gì. (Hoặc đúng câu hỏi version.3 khi sử dụng mutex và khi sử dụng nhị phân semaphore, vì không có so sánh với nhị phân-semaphore.) Sử dụng mutex khi 1. bạn muốn có một hành vi tùy chỉnh, không được cung cấp bởi semaphore nhị phân, chẳng hạn như spin-lock hoặc fast-lock hoặc recursive-locks. Bạn thường có thể tùy chỉnh mutexes với các thuộc tính, nhưng tùy biến semaphore là gì, nhưng viết semaphore mới. 2. bạn muốn trọng lượng nhẹ HOẶC nhanh hơn nguyên thủy

Sử dụng các ẩn dụ, khi bạn muốn chính xác nó được cung cấp.

Nếu bạn không hiểu những gì đang được cung cấp bởi việc thực hiện nhị phân-semaphore, sau đó IMHO, sử dụng mutex.

Và cuối cùng đọc một cuốn sách thay vì chỉ dựa vào SO.

5

Tôi nghĩ câu hỏi nên là sự khác biệt giữa mutex và nhị phân semaphore.

Mutex = Đây là cơ chế khóa quyền sở hữu, chỉ chủ đề có được khóa mới có thể nhả khóa.

nhị phân Semaphore = Đây là cơ chế tín hiệu, bất kỳ chuỗi ưu tiên cao hơn nào khác nếu muốn có thể báo hiệu và lấy khóa.

1

Một mutex là trường hợp đặc biệt của semaphore. Một semaphore cho phép một số chủ đề đi vào phần quan trọng. Khi tạo một semaphore bạn xác định làm thế nào có thể đề được cho phép trong phần quan trọng. Tất nhiên mã của bạn phải có khả năng xử lý một số truy cập đến phần quan trọng này.

2

Mutex là để bảo vệ tài nguyên được chia sẻ.
Semaphore là gửi các chủ đề.

Mutex:
Hãy tưởng tượng rằng có một số vé để bán. Chúng tôi có thể mô phỏng một trường hợp nhiều người mua vé cùng một lúc: mỗi người là một chủ đề để mua vé. Rõ ràng chúng ta cần phải sử dụng mutex để bảo vệ vé vì nó là tài nguyên được chia sẻ.


Semaphore:
Hãy tưởng tượng rằng chúng ta cần phải làm một phép tính như sau:

c = a + b; 

Ngoài ra, chúng ta cần một hàm geta() để tính toán a, một chức năng getb() để tính toán b và một hàm getc() để thực hiện phép tính c = a + b.

Rõ ràng, chúng tôi không thể thực hiện c = a + b trừ khi geta()getb() đã được hoàn tất.
Nếu ba chức năng là ba chủ đề, chúng ta cần phải gửi ba chủ đề.

int a, b, c; 
void geta() 
{ 
    a = calculatea(); 
    semaphore_increase(); 
} 

void getb() 
{ 
    b = calculateb(); 
    semaphore_increase(); 
} 

void getc() 
{ 
    semaphore_decrease(); 
    semaphore_decrease(); 
    c = a + b; 
} 

t1 = thread_create(geta); 
t2 = thread_create(getb); 
t3 = thread_create(getc); 
thread_join(t3); 

Với sự giúp đỡ của các semaphore, các mã trên có thể chắc chắn rằng t3 sẽ không làm công việc của mình cho đến khi t1t2 đã làm công việc của họ.

Trong một từ, semaphore là để làm cho các chủ đề thực hiện như một trật tự hợp lý trong khi mutex là để bảo vệ tài nguyên được chia sẻ.
Vì vậy, chúng không giống nhau ngay cả khi một số người luôn nói rằng mutex là một semaphore đặc biệt với giá trị ban đầu 1. Bạn có thể nói như thế này quá nhưng xin lưu ý rằng chúng được sử dụng trong các trường hợp khác nhau. Đừng thay thế cái này bằng cái khác ngay cả khi bạn có thể làm điều đó.

+0

Vé bán là một ví dụ gọn gàng. ví dụ semaphore là bit không rõ ràng (với tôi anyway). – prayagupd

+1

@prayagupd Ví dụ Semaphore là tạo các chuỗi theo thứ tự nào đó trong khi vé bán không cần bất kỳ thứ tự nào. Nếu có ba người: a, b và c. Khi họ đến mua vé, chúng tôi không quan tâm đến thứ tự mua vé. Tuy nhiên, nếu chúng ta tính toán như vậy: 'x = getx(); y = gety(); z = x + y; 'Vì lý do nào đó, chúng ta sử dụng ba luồng để làm ba thứ, bây giờ thứ tự của các luồng là rất quan trọng bởi vì chúng ta không thể làm' x + y' trừ khi 'getx' và' gety' đã hoàn thành . Trong một từ, semaphore được sử dụng khi chúng ta quan tâm đến thứ tự thực hiện đa luồng. – Yves

+0

giúp bạn. Nghe có vẻ tương tự như [rào cản] (https://en.wikipedia.org/wiki/Barrier_ (computer_science)). Tôi có thể nói rằng chờ cho đến khi các chuỗi 'x' và' y' được hoàn thành, sau đó tính 'z = x + y'. Tôi biết java có ['CyclicBarrier'] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CyclicBarrier.html). Ngoài ra, tôi không chắc liệu tôi có thể nói 'mapreduce' là semaphore usecase nữa, bởi vì tôi không thể 'reduce' cho đến khi tất cả' map 'được hoàn thành. – prayagupd

0

Tất cả các câu trả lời trên đều có chất lượng tốt, nhưng điều này chỉ để tên memorize.The Mutex có nguồn gốc từ loại trừ lẫn nhau do đó bạn là động lực để nghĩ đến một khóa mutex như loại trừ lẫn nhau giữa hai như trong một lần duy nhất, và nếu tôi sở hữu nó, bạn có thể có nó chỉ sau khi tôi phát hành nó. Mặt khác trường hợp đó không tồn tại cho Semaphore giống như một tín hiệu giao thông (mà từ Semaphore cũng có nghĩa là) .