Sự khác biệt giữa semaphore nhị phân và mutex


819

Có sự khác biệt nào giữa một semaphore nhị phân và mutex hay về cơ bản chúng giống nhau không?


11
Chúng giống nhau về mặt ngữ nghĩa, nhưng trong thực tế, bạn sẽ nhận thấy những khác biệt kỳ lạ (đặc biệt là trên Windows).
Michael Foukarakis

5
@Michael Foukarakis: sự khác biệt kỳ lạ là gì?
Phi

2
Tôi cho rằng kỳ lạ không phải là biểu hiện chính xác. Một mutex cũng hỗ trợ quyền sở hữu và đôi khi thử lại. Đây là trường hợp trong Windows. Ngoài ra, semaphores trong Windows được triển khai trên đầu các đối tượng Sự kiện, tuy nhiên, tôi không chắc về ý nghĩa thực tế của việc này.
Michael Foukarakis

1
Thảo luận tương tự trong stackoverflow.com/questions
4039899 / Mạnh

2
@philipxy Hoàn toàn giấu 'rn' thay cho 'm'.
Mooncrater

Câu trả lời:


691

Họ KHÔNG phải là điều tương tự. Chúng được sử dụng cho các mục đích khác nhau!
Mặc dù cả hai loại semaphores đều có trạng thái đầy đủ / trống và sử dụng cùng một API, cách sử dụng của chúng rất khác nhau.

Các ngữ nghĩa loại trừ lẫn nhau Các ngữ nghĩa loại trừ
lẫn nhau được sử dụng để bảo vệ các tài nguyên được chia sẻ (cấu trúc dữ liệu, tệp, v.v.).

Một semaphore Mutex được "sở hữu" bởi nhiệm vụ đảm nhận nó. Nếu Nhiệm vụ B cố gắng semGive một mutex hiện đang được thực hiện bởi Nhiệm vụ A, cuộc gọi của Nhiệm vụ B sẽ trả về lỗi và không thành công.

Mutexes luôn sử dụng trình tự sau:

  - Bán kết
  - Phần quan trọng
  - SemGive

Đây là một ví dụ đơn giản:

  Chủ đề A Chủ đề B
   Lấy Mutex
     tiếp cận thông tin
     ... Lấy Mutex <== Sẽ chặn
     ...
   Cung cấp dữ liệu truy cập Mutex <== Unblocks
                                  ...
                                Tặng Mutex

Semaphore
nhị phân nhị phân Semaphore giải quyết một câu hỏi hoàn toàn khác nhau:

  • Nhiệm vụ B đang chờ đợi điều gì đó xảy ra (ví dụ một cảm biến bị vấp).
  • Các chuyến đi cảm biến và một tuyến dịch vụ gián đoạn chạy. Nó cần phải thông báo một nhiệm vụ của chuyến đi.
  • Nhiệm vụ B nên chạy và thực hiện các hành động thích hợp cho chuyến đi cảm biến. Sau đó quay lại chờ đợi.

   Task A                      Task B
   ...                         Take BinSemaphore   <== wait for something
   Do Something Noteworthy
   Give BinSemaphore           do something    <== unblocks

Lưu ý rằng với một semaphore nhị phân, B có thể lấy semaphore và A để cung cấp cho nó.
Một lần nữa, một semaphore nhị phân KHÔNG bảo vệ tài nguyên khỏi sự truy cập. Hành động cho và nhận một semaphore về cơ bản được tách rời.
Nó thường không có ý nghĩa đối với cùng một nhiệm vụ để đưa ra và thực hiện trên cùng một semaphore nhị phân.


12
Không phải là một mutex tốt hơn một semaphore nhị phân sao? Vì nó không có nghĩa gì nếu ai đó phát hành một khóa mà anh ta không thực sự giữ.
Pacerier

111
Họ có những mục đích khác nhau. Mutex là dành riêng cho truy cập vào một tài nguyên. Một semaphore nhị phân nên được sử dụng để đồng bộ hóa (tức là "Này ai đó! Điều này đã xảy ra!"). "Người cho" nhị phân chỉ đơn giản thông báo cho bất cứ ai là "người nhận" rằng những gì họ đang chờ đợi đã xảy ra.
Benoit

5
@Pacerier Bạn đang nhầm lẫn mục đích. Một mutex được dự định bảo vệ một khu vực quan trọng. Bạn đúng là không có ý nghĩa khi sử dụng Semaphore nhị phân. Tôi sẽ cập nhật câu trả lời để giải thích mục đích của mỗi.
Benoit

4
@Benoit Vì vậy, chúng ta có thể nói rằng Mutex được sử dụng cho nguyên tử và Semaphore nhị phân cho phối cảnh đặt hàng vì Nhiệm vụ B sẽ chờ Nhiệm vụ A báo hiệu việc phát hành khóa vốn đảm bảo đặt hàng các hoạt động trên cấu trúc dữ liệu?
abhi

1
@abhi Đó là một cách tốt để xem xét nó cho Mutex. Tuy nhiên, tùy thuộc vào HĐH, bạn có thể có nhiều hơn một người nhận đang chờ đợi trên một semaphore nhị phân. Trong trường hợp đó, chỉ một trong số các khách hàng sẽ nhận được sem nhị phân. Những người khác sẽ đợi một người tiếp theo. Là thứ tự nhận được biết hoặc được bảo đảm? Phụ thuộc vào hệ điều hành.
Benoit

446
  • Một mutex có thể được phát hành chỉ bởi các chủ đề đã có được nó .
  • Một semaphore nhị phân có thể được báo hiệu bởi bất kỳ chủ đề (hoặc quá trình).

vì vậy semaphores phù hợp hơn cho một số vấn đề đồng bộ hóa như nhà sản xuất-người tiêu dùng.

Trên Windows, semaphores nhị phân giống như các đối tượng sự kiện hơn là mutexes.


34
Mutex can be released only by thread that had acquired it- Tôi vừa thử với một chương trình dựa trên pthread_mutex đơn giản, một luồng có thể mở khóa mutex bị khóa trong luồng chính
daisy

15
@ warl0ck Theo trang man của pthread_mutex_lock linux.die.net/man/3/pthread_mutex_lock : "Nếu loại mutex là PTHREAD_MUTEX_ERRORCHECK, thì việc kiểm tra lỗi sẽ được cung cấp .... không bị khóa hoặc một mutex được mở khóa, một lỗi sẽ được trả lại. "
amit

47
@ warl0ck Vui lòng xem stackoverflow.com/a/5492499/385064 'Pthreads có 3 loại mutexes khác nhau: Mutex nhanh, mutex đệ quy và kiểm tra lỗi mutex. Bạn đã sử dụng một mutex nhanh, vì lý do hiệu suất, sẽ không kiểm tra lỗi này. Nếu bạn sử dụng kiểm tra lỗi mutex trên Linux, bạn sẽ thấy bạn nhận được kết quả mà bạn mong đợi. '
FrostNovaZzz

1
Trong mã của chúng tôi, chúng tôi cũng đã sử dụng mutex cho mục đích đồng bộ hóa. Chủ đề khóa mutex một lần nữa cố gắng khóa mutex. Sau đó, nó chuyển sang trạng thái bị chặn. Chúng tôi đã thấy rằng chúng tôi có thể mở khóa này từ một luồng khác. đồng bộ hóa giữa hai chúng tôi chỉ sử dụng tiêu chuẩn posix. Vì vậy, sự khác biệt chính được đặt ra giữa mutex và semaphore nhị phân có vẻ mơ hồ.
achoora

1
@achoora Tôi đồng ý rằng việc chuyên môn hóa semaphore để đồng bộ hóa là sai. Trên thực tế tất cả các mutex, binary-semaphore, rào cản, đường ống là các mẫu khác nhau để đồng bộ hóa. Trong phối cảnh thiết kế, mutex giống như mô hình trạng thái trong đó thuật toán được chọn bởi trạng thái có thể thay đổi trạng thái. Nhị phân-semaphore giống như mẫu chiến lược trong đó thuật toán bên ngoài có thể thay đổi trạng thái và cuối cùng là thuật toán / chiến lược được chọn để chạy.
shuva

442

Ví dụ về Nhà vệ sinh là một sự tương tự thú vị:

Đột biến:

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

Chính thức: "Mutex thường được sử dụng để tuần tự hóa quyền truy cập vào một phần của mã được cấp lại mà không thể được thực thi đồ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 truy cập vào phần đó để đợi cho đến khi luồng đầu tiên thoát khỏi phần đó. " Tham chiếu: Thư viện nhà phát triển Symbian

(Một mutex thực sự là một semaphore có giá trị 1.)

Semaphore:

Là số lượng chìa khóa nhà vệ sinh giống hệt miễn phí. Ví dụ, giả sử chúng ta có bốn nhà vệ sinh với ổ khóa và chìa khóa giống hệt nhau. Số lượng semaphore - số lượng khóa - được đặt thành 4 ở đầu (tất cả bốn nhà vệ sinh đều miễn phí), sau đó giá trị đếm sẽ giảm khi mọi người đến. Nếu tất cả các nhà vệ sinh đều đầy, tức là. không còn khóa miễn phí, số lượng 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 khóa miễn phí) và được 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 một tài nguyên được chia sẻ lên đến một số lượng tối đa. 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ọ đã sử dụng tài nguyên (tăng semaphore). " Tham chiếu: Thư viện nhà phát triển Symbian


234
... nhưng điều này liên quan đến mutex vs đếm semaphore. Câu hỏi đã được hỏi về nhị phân.
Roman Nikoveko

24
Mặc dù những gì được nói bởi david là chính xác, nhưng nó KHÔNG phải là câu trả lời cho câu hỏi được hỏi. Câu trả lời của Mladen Jankovic là câu trả lời cho câu hỏi được hỏi, điểm được thực hiện để phân biệt "nhị phân-semaphore" và "mutex".
Ajeet Ganga

13
Thật không may, câu trả lời không chính xác này có nhiều phiếu hơn câu trả lời hay nhất của
@Benoit

6
Câu trả lời này là sai lệch. Chỉ nên so sánh với Baph Semaphore.
Hemanth

3
Điều này cũng cho thấy có vấn đề với việc sử dụng semaphore đếm để bảo vệ tài nguyên được chia sẻ: nếu các khóa thực sự giống hệt nhau và nhà vệ sinh được mở khóa bằng khóa và không có cơ chế nào khác để phân phối việc sử dụng tủ, sau đó: (1) người dùng mở khóa, nhập và bắt đầu sử dụng tủ đầu tiên. (2) người dùng tiếp theo mở khóa, nhập và bắt đầu sử dụng tủ đầu tiên ...
Technophile

151

Những bài viết hay về chủ đề này:

Từ phần 2:

Mutex tương tự như các nguyên tắc của semaphore nhị phân với một điểm khác biệt đáng kể: nguyên tắc sở hữu. Quyền sở hữu là khái niệm đơn giản mà khi một tác vụ khóa (mua lại) một mutex chỉ có nó mới có thể mở khóa (phát hành) nó. Nếu một tác vụ cố gắng mở khóa một mutex mà nó không bị khóa (do đó không sở hữu) thì sẽ gặp phải một điều kiện lỗi và quan trọng nhất là mutex không được mở khóa. Nếu đối tượng loại trừ lẫn nhau không có quyền sở hữu thì không liên quan đến cái mà nó được gọi, nó không phải là một mutex.


Cảm ơn các liên kết, giải thích có xuất sắc. Liên kết đã thay đổi: fableshas.com/blog/2009/09/ Lần (Sử dụng <Trước và Tiếp theo> để điều hướng đến hai bài viết khác.
Aaron H.

@Aaron Tôi đã sửa các liên kết
Thẩm phán Maygarden

Lưu ý - việc thiếu quyền sở hữu cũng ngăn hệ điều hành hoạt động xung quanh ưu tiên đảo ngược. Vì lý do này, tôi thường sử dụng các biến điều kiện trái ngược với semaphores cho kiến ​​trúc nhà sản xuất / người tiêu dùng.
kgriffs

1
+1 kẻ thù liên kết bài viết tuyệt vời. Bài viết hay nhất giải thích semaphore và mutex với "what-it-is" và "what-it-does" tính toán.llnl.gov/tutorials/pthreads Tôi đã sử dụng bài viết này làm tài liệu tham khảo đằng sau cảnh của mình mutex / điều kiện và các cấu trúc khác được xây dựng trên đỉnh của chúng như semaphore / rào cản / người đọc-nhà văn, nhưng không nơi nào rõ ràng và súc tích về các vấn đề phải đối mặt với các cấu trúc. Tóm lại nó là tài liệu tham khảo. :)
Ajeet Ganga

dễ hiểu hơn các câu trả lời khác.
BinaryTreeee

101

Vì không có câu trả lời nào ở trên xóa được sự nhầm lẫn, đây là câu trả lời cho sự nhầm lẫn của tôi.

Nói đúng ra, mutex là một cơ chế khóa được sử dụng để đồng bộ hóa quyền truy cập vào tài nguyên. Chỉ một tác vụ (có thể là một luồng hoặc quá trình dựa trên sự trừu tượng hóa hệ điều hành) có thể có được mutex. Điều đó có nghĩa là sẽ có quyền sở hữu liên quan đến mutex và chỉ chủ sở hữu mới có thể phát hành khóa (mutex).

Semaphore là cơ chế báo hiệu (Tôi đã hoàn thành, bạn có thể thực hiện trên loại tín hiệu này). Ví dụ: nếu bạn đang nghe các bài hát (giả sử là một tác vụ) trên điện thoại di động của mình và đồng thời bạn của bạn gọi cho bạn, một ngắt sẽ được kích hoạt theo đó một thói quen dịch vụ ngắt (ISR) sẽ báo hiệu tác vụ xử lý cuộc gọi thức dậy .

Nguồn: http://www.geekforgeek.org/mutex-vs-semaphore/


42

Ngữ nghĩa đồng bộ hóa của chúng rất khác nhau:

  • mutexes cho phép tuần tự hóa quyền truy cập vào một tài nguyên nhất định, tức là nhiều luồng chờ khóa, mỗi lần một luồng và như đã nói trước đó, luồng sở hữu khóa cho đến khi hoàn thành: chỉ luồng này có thể mở khóa.
  • một semaphore nhị phân là một bộ đếm có giá trị 0 và 1: một tác vụ chặn nó cho đến khi bất kỳ tác vụ nào thực hiện sem_post. Semaphore quảng cáo rằng một tài nguyên có sẵn và nó cung cấp cơ chế để chờ cho đến khi nó được báo hiệu là có sẵn.

Như vậy, người ta có thể thấy một mutex như một mã thông báo được truyền từ nhiệm vụ này sang nhiệm vụ khác và một semaphore là đèn đỏ giao thông (nó báo hiệu cho ai đó rằng nó có thể tiến hành).


23

Ở cấp độ lý thuyết, chúng không khác nhau về mặt ngữ nghĩa. Bạn có thể thực hiện một mutex bằng semaphores hoặc ngược lại (xem ví dụ ở đây ). Trong thực tế, việc thực hiện là khác nhau và họ cung cấp các dịch vụ hơi khác nhau.

Sự khác biệt thực tế (về các dịch vụ hệ thống xung quanh chúng) là việc triển khai một mutex nhằm mục đích trở thành một cơ chế đồng bộ hóa nhẹ hơn. Trong oracle-speak, mutexes được gọi là chốt và semaphores được gọi là chờ đợi .

Ở cấp độ thấp nhất, họ sử dụng một số loại thử nghiệm nguyên tử cơ chế thiết lập . Điều này đọc giá trị hiện tại của một vị trí bộ nhớ, tính toán một số loại điều kiện và viết ra một giá trị tại vị trí đó trong một lệnh duy nhất không thể bị gián đoạn . Điều này có nghĩa là bạn có thể có được một mutex và kiểm tra xem có ai khác có nó trước bạn không.

Một triển khai mutex điển hình có một quy trình hoặc luồng thực hiện lệnh test-and-set và đánh giá xem có thứ gì khác đã đặt mutex không. Một điểm quan trọng ở đây là không có sự tương tác với bộ lập lịch , vì vậy chúng tôi không có ý tưởng (và không quan tâm) người đã đặt khóa. Sau đó, chúng tôi hoặc từ bỏ lát cắt thời gian của mình và thử lại khi tác vụ được lên lịch lại hoặc thực hiện khóa xoay . Khóa xoay là một thuật toán như:

Count down from 5000:
     i. Execute the test-and-set instruction
    ii. If the mutex is clear, we have acquired it in the previous instruction 
        so we can exit the loop
   iii. When we get to zero, give up our time slice.

Khi chúng tôi thực hiện xong mã được bảo vệ của chúng tôi (được gọi là phần quan trọng ), chúng tôi chỉ đặt giá trị mutex thành 0 hoặc bất cứ điều gì có nghĩa là 'rõ ràng'. Nếu nhiều tác vụ đang cố gắng để có được mutex, thì tác vụ tiếp theo sẽ được lên lịch sau khi mutex được phát hành sẽ có quyền truy cập vào tài nguyên. Thông thường, bạn sẽ sử dụng mutexes để kiểm soát tài nguyên được đồng bộ hóa, nơi chỉ cần truy cập độc quyền trong khoảng thời gian rất ngắn, thông thường để thực hiện cập nhật lên cấu trúc dữ liệu được chia sẻ.

Một semaphore là một cấu trúc dữ liệu được đồng bộ hóa (thường sử dụng một mutex) có số đếm và một số trình bao bọc cuộc gọi hệ thống tương tác với bộ lập lịch ở độ sâu hơn một chút so với các thư viện mutex. Semaphores được tăng lên và giảm dần và được sử dụng để chặn các nhiệm vụ cho đến khi một cái gì đó khác đã sẵn sàng. Xem Vấn đề về Nhà sản xuất / Người tiêu dùng để biết ví dụ đơn giản về điều này. Semaphores được khởi tạo cho một số giá trị - một semaphore nhị phân chỉ là một trường hợp đặc biệt trong đó semaphore được khởi tạo thành 1. Đăng lên một semaphore có tác dụng đánh thức một quá trình chờ đợi.

Một thuật toán semaphore cơ bản trông giống như:

(somewhere in the program startup)
Initialise the semaphore to its start-up value.

Acquiring a semaphore
   i. (synchronised) Attempt to decrement the semaphore value
  ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.

Posting a semaphore
   i. (synchronised) Increment the semaphore value
  ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.  
 iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.

Trong trường hợp của một semaphore nhị phân, sự khác biệt thực tế chính giữa hai là bản chất của các dịch vụ hệ thống xung quanh cấu trúc dữ liệu thực tế.

EDIT: Như evan đã chỉ ra một cách đúng đắn, spinlocks sẽ làm chậm một bộ vi xử lý. Bạn sẽ chỉ sử dụng một spinlock trên hộp đa bộ xử lý vì trên một bộ xử lý duy nhất, quá trình giữ mutex sẽ không bao giờ thiết lập lại nó trong khi một tác vụ khác đang chạy. Spinlocks chỉ hữu ích trên các kiến ​​trúc đa bộ xử lý.


1
Tôi không nghĩ rằng đó là một thực tế phổ biến cho một mutex được thực hiện với spinlocks. Trên một máy Uni-Proc, điều này sẽ hoàn toàn khủng khiếp đối với hiệu suất.
Evan Teran

Thông thường bạn sẽ chỉ sử dụng spinlocks trên các hệ thống đa bộ xử lý.
Mối quan tâmOfTunbridgeWells

Ngay cả trên SMP, sau khi quay một vài lần, bạn lại rơi vào trạng thái ngủ / thức được hỗ trợ bởi hệ điều hành. (ví dụ như Linux futexgọi hệ thống tồn tại để hỗ trợ độ trễ thấp userspace mutex / semaphore triển khai. en.wikipedia.org/wiki/Futex ) Trong con đường nhanh không tranh chấp, hoặc nếu tài nguyên trở nên sớm có sẵn, bạn không bao giờ có những phí của một cuộc gọi hệ thống. Nhưng bạn không dành nhiều hơn một vài giây chờ đợi bận rộn (quay). Tất nhiên, điều chỉnh các tham số của back-loop spin và chờ là phụ thuộc vào phần cứng và khối lượng công việc, nhưng thư viện tiêu chuẩn thường có các lựa chọn hợp lý.
Peter Cordes

19

Mặc dù mutex & semaphores được sử dụng làm nguyên thủy đồng bộ hóa, có một sự khác biệt lớn giữa chúng. Trong trường hợp của mutex, chỉ có luồng bị khóa hoặc có được mutex mới có thể mở khóa nó. Trong trường hợp của một semaphore, một luồng chờ trên một semaphore có thể được báo hiệu bởi một luồng khác. Một số hệ điều hành hỗ trợ sử dụng mutex & semaphores giữa tiến trình. Thông thường việc sử dụng là tạo ra trong bộ nhớ chia sẻ.


"Có thể được báo hiệu bởi một chủ đề khác" nghĩa là gì cho một ví dụ.
Myanju

15

Mutex: Giả sử chúng ta có chủ đề phần quan trọng mà T1 muốn truy cập thì nó sẽ thực hiện theo các bước dưới đây. T1:

  1. Khóa
  2. Sử dụng phần quan trọng
  3. Mở khóa

Semaphore nhị phân: Nó hoạt động dựa trên tín hiệu chờ đợi và tín hiệu. Wait (s) giảm giá trị "s" xuống một giá trị "s" thường được khởi tạo với giá trị "1", tín hiệu (s) tăng giá trị "s" lên một. nếu giá trị "s" là 1 nghĩa là không ai sử dụng phần quan trọng, khi giá trị bằng 0 nghĩa là phần quan trọng đang được sử dụng. giả sử luồng T2 đang sử dụng phần quan trọng thì nó sẽ thực hiện theo các bước dưới đây. T2:

  1. Wait (s) // giá trị s ban đầu là một sau khi gọi chờ, giá trị của nó giảm đi một, tức là 0
  2. Sử dụng phần quan trọng
  3. signal (s) // bây giờ giá trị s được tăng lên và nó trở thành 1

Sự khác biệt chính giữa Mutex và Baph semaphore là trong Mutext nếu luồng khóa phần quan trọng thì nó phải mở khóa phần quan trọng, không có luồng nào khác có thể mở khóa nó, nhưng trong trường hợp semaphore nhị phân nếu một luồng khóa phần quan trọng sử dụng chức năng Wait (s) thì giá trị của s trở thành "0" và không ai có thể truy cập nó cho đến khi giá trị của "s" trở thành 1 nhưng giả sử một số tín hiệu gọi luồng khác thì giá trị của "s" trở thành 1 và nó cho phép chức năng khác sử dụng phần quan trọng. do đó trong chủ đề semaphore nhị phân không có quyền sở hữu.


12

Trên Windows, có hai điểm khác biệt giữa mutexes và semaphores:

  1. Một mutex chỉ có thể được phát hành bởi luồng có quyền sở hữu, tức là luồng trước đây được gọi là hàm Wait, (hoặc quyền sở hữu khi tạo nó). Một semaphore có thể được phát hành bởi bất kỳ chủ đề.

  2. Một chuỗi có thể gọi một hàm chờ liên tục trên một mutex mà không chặn. Tuy nhiên, nếu bạn gọi một hàm chờ hai lần trên một semaphore nhị phân mà không giải phóng semaphore ở giữa, thì luồng sẽ chặn.


4
Câu trả lời tốt. Trong # 2, bạn đang mô tả một mutex đệ quy - không phải tất cả các mutex đều nhất thiết phải đệ quy. Ví dụ: cs.wustl.edu/~schmidt/ACE.FAQ.html#Q14
Dan

10

Bạn rõ ràng sử dụng mutex để khóa dữ liệu trong một luồng được truy cập bởi một luồng khác cùng một lúc. Giả sử rằng bạn vừa gọi lock()và đang trong quá trình truy cập dữ liệu. Điều này có nghĩa là bạn không mong đợi bất kỳ luồng nào khác (hoặc một phiên bản khác của cùng mã luồng) truy cập vào cùng một dữ liệu bị khóa bởi cùng một mutex. Đó là, nếu đó là cùng một mã luồng được thực thi trên một thể hiện luồng khác, chạm vào khóa, thìlock()nên chặn dòng điều khiển ở đó. Điều này áp dụng cho một luồng sử dụng một mã luồng khác, cũng đang truy cập cùng một dữ liệu và cũng bị khóa bởi cùng một mutex. Trong trường hợp này, bạn vẫn đang trong quá trình truy cập dữ liệu và bạn có thể mất 15 giây nữa để mở khóa mutex (để luồng khác bị chặn trong khóa mutex sẽ bỏ chặn và sẽ cho phép điều khiển truy cập dữ liệu). Bạn có bằng bất cứ giá nào cho phép một luồng khác chỉ mở khóa cùng một mutex không, và lần lượt, cho phép luồng đang chờ (chặn) trong khóa mutex để bỏ chặn và truy cập dữ liệu? Hy vọng bạn có những gì tôi đang nói ở đây? Theo, đồng ý với định nghĩa phổ quát!,

  • với mutexex, điều này không thể xảy ra. Không có chủ đề khác có thể mở khóa khóa trong chủ đề của bạn
  • với nhóm nhị phân-semaphore, điều này có thể xảy ra. Bất kỳ chủ đề khác có thể mở khóa khóa trong chủ đề của bạn

Vì vậy, nếu bạn rất đặc biệt về việc sử dụng semaphore nhị phân thay vì mutex, thì bạn nên rất cẩn thận trong phạm vi phạm vi khóa các khóa và mở khóa. Ý tôi là, mọi luồng điều khiển chạm vào mọi khóa đều phải thực hiện một cuộc gọi mở khóa, cũng không nên có bất kỳ khóa mở khóa đầu tiên nào, thay vào đó, nó phải luôn luôn là khóa đầu tiên.


10

Mutex được sử dụng cho "Cơ chế khóa". một quá trình tại một thời điểm có thể sử dụng tài nguyên được chia sẻ

trong khi

Semaphores được sử dụng cho "Cơ chế báo hiệu" như "Tôi đã hoàn thành, bây giờ có thể tiếp tục"


9

Quan niệm:

Một vài bài báo nói rằng "semaphore nhị phân và mutex giống nhau" hoặc "Semaphore với giá trị 1 là mutex" nhưng sự khác biệt cơ bản là Mutex chỉ có thể được phát hành bởi luồng đã thu được nó, trong khi bạn có thể báo hiệu semaphore từ bất kỳ luồng nào khác

Những điểm chính:

• Một chuỗi có thể có được nhiều hơn một khóa (Mutex).

• Một mutex có thể bị khóa nhiều lần chỉ khi một mutex đệ quy, ở đây khóa và mở khóa cho mutex phải giống nhau

• Nếu một chuỗi đã khóa mutex, cố gắng khóa mutex lại, nó sẽ vào danh sách chờ của mutex đó, dẫn đến bế tắc.

• semaphore nhị phân và mutex giống nhau nhưng không giống nhau.

• Mutex hoạt động tốn kém do các giao thức bảo vệ liên quan đến nó.

• Mục đích chính của mutex là đạt được quyền truy cập nguyên tử hoặc khóa tài nguyên


8

Một Mutex kiểm soát quyền truy cập vào một nguồn tài nguyên được chia sẻ duy nhất. Nó cung cấp các hoạt động để có được () quyền truy cập vào tài nguyên đó và giải phóng () nó khi hoàn thành.

Một Semaphore kiểm soát quyền truy cập vào hồ bơi chung các nguồn tài nguyên. Nó cung cấp các hoạt động cho Wait () cho đến khi một trong các tài nguyên trong nhóm trở nên khả dụng và Signal () khi được đưa trở lại nhóm.

Khi số lượng tài nguyên mà Semaphore bảo vệ lớn hơn 1, nó được gọi là Semaphore đếm . Khi nó kiểm soát một tài nguyên, nó được gọi là Semaphore Boolean . Một semaphore boolean tương đương với một mutex.

Do đó, Semaphore là một mức độ trừu tượng cao hơn Mutex. Một Mutex có thể được thực hiện bằng cách sử dụng Semaphore nhưng không phải là cách khác.


6

Câu hỏi được sửa đổi là - Sự khác biệt giữa một mutex và một semaphore "nhị phân" trong "Linux" là gì?

Trả lời: Sau đây là những khác biệt - i) Phạm vi - Phạm vi của mutex nằm trong một không gian địa chỉ quy trình đã tạo ra nó và được sử dụng để đồng bộ hóa các luồng. Trong khi semaphore có thể được sử dụng trên không gian quá trình và do đó nó có thể được sử dụng để đồng bộ hóa quá trình.

ii) Mutex nhẹ và nhanh hơn semaphore. Futex thậm chí còn nhanh hơn.

iii) Mutex có thể được mua lại bởi cùng một chủ đề thành công nhiều lần với điều kiện là nó sẽ phát hành cùng một số lần. Chủ đề khác cố gắng để có được sẽ chặn. Trong trường hợp semaphore nếu cùng một quá trình cố gắng để có được nó một lần nữa thì nó bị chặn vì nó chỉ có thể được mua một lần.


tôi sai. ii) Nguồn? iii) Nó phụ thuộc.
tò mò

6

Khác biệt giữa Semaphore nhị phân và Mutex: OWNERSHIP: Semaphores có thể được báo hiệu (đăng) ngay cả từ một chủ sở hữu không hiện tại. Nó có nghĩa là bạn có thể chỉ cần đăng từ bất kỳ chủ đề khác, mặc dù bạn không phải là chủ sở hữu.

Semaphore là một tài sản công cộng trong quá trình, Nó có thể được đăng đơn giản bởi một chủ đề không phải chủ sở hữu. Vui lòng đánh dấu sự khác biệt này trong các chữ cái BÓNG, nó có nghĩa là rất nhiều.


5

Mutex hoạt động để chặn khu vực quan trọng, nhưng Semaphore hoạt động rất tốt.


5

http://www.geekforgeek.org/archives/9102 thảo luận chi tiết.

Mutexlà cơ chế khóa được sử dụng để đồng bộ hóa truy cập vào tài nguyên. Semaphorelà cơ chế báo hiệu.

Tùy thuộc vào lập trình viên nếu anh ấy / cô ấy muốn sử dụng semaphore nhị phân thay cho mutex.


4

Ngoài thực tế là các mutexes có chủ sở hữu, hai đối tượng có thể được tối ưu hóa cho việc sử dụng khác nhau. Mutexes được thiết kế để được tổ chức chỉ trong một thời gian ngắn; vi phạm điều này có thể gây ra hiệu suất kém và lập kế hoạch không công bằng. Ví dụ, một luồng đang chạy có thể được phép có được một mutex, mặc dù một luồng khác đã bị chặn trên nó. Semaphores có thể cung cấp công bằng hơn, hoặc công bằng có thể bị buộc sử dụng một số biến điều kiện.


Trong trường hợp cụ thể nào là sự công bằng được đảm bảo cho semaphores nhưng không phải cho mutexes?
tò mò

1
POSIX có những yêu cầu cụ thể mà chủ đề nên được đánh thức bởi sem_post()cho SCHED_FIFOSCHED_RR(cả hai đều không mặc định): các chủ đề ưu tiên cao nhất, và nếu có nhiều với các ưu tiên như nhau, các chủ đề đã được chờ đợi lâu nhất. OpenSolaris tuân theo quy tắc FIFO này ở một mức độ nào đó ngay cả đối với việc lập lịch trình bình thường. Đối với glibc và FreeBSD, việc mở khóa một mutex đơn giản (nghĩa là không ưu tiên bảo vệ hoặc kế thừa ưu tiên) và đăng một semaphore về cơ bản là giống nhau, đánh dấu đối tượng là đã mở khóa và sau đó, nếu có thể có các chuỗi chờ, hãy gọi kernel để đánh thức.
jilles

4

Trong cửa sổ sự khác biệt là như dưới đây. MUTEX: quá trình thực hiện thành công chờ đợi phải thực hiện tín hiệu và ngược lại. CÁC HÌNH ẢNH BÌNH LUẬN: Các quy trình khác nhau có thể thực hiện thao tác chờ hoặc tín hiệu trên một semaphore.


4

Mặc dù một semaphore nhị phân có thể được sử dụng như một mutex, một mutex là một trường hợp sử dụng cụ thể hơn, trong đó chỉ có quá trình khóa mutex được cho là để mở khóa nó. Hạn chế quyền sở hữu này giúp bảo vệ chống lại:

  • Tình cờ phát hành
  • Bế tắc đệ quy
  • Nhiệm vụ bế tắc

Những ràng buộc này không phải lúc nào cũng có mặt vì chúng làm giảm tốc độ. Trong quá trình phát triển mã của bạn, bạn có thể kích hoạt các kiểm tra này tạm thời.

ví dụ: bạn có thể bật thuộc tính Kiểm tra lỗi trong mutex của bạn. Lỗi khi kiểm tra mutexes trở lại EDEADLKnếu bạn cố gắng khóa cùng một lần hai lần và EPERMnếu bạn mở khóa một mutex không phải của bạn.

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

Sau khi khởi tạo, chúng ta có thể đặt các kiểm tra này vào mã của mình như sau:

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");

4

Khái niệm này là rõ ràng với tôi sau khi đi qua bài viết trên. Nhưng có một số câu hỏi còn sót lại. Vì vậy, tôi đã viết đoạn mã nhỏ này.

Khi chúng tôi cố gắng đưa ra một semaphore mà không lấy nó, nó sẽ đi qua. Nhưng, khi bạn cố gắng đưa ra một mutex mà không lấy nó, nó đã thất bại. Tôi đã thử nghiệm điều này trên nền tảng Windows. Cho phép USE_MUTEX chạy cùng mã bằng MUTEX.

#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1

DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );

HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;


int main(void)
{

#ifdef USE_MUTEX
    ghMutex = CreateMutex( NULL, FALSE, NULL);
    if (ghMutex  == NULL) 
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }
#else
    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
    ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }
#endif
    // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);  
    if ( Handle_Of_Thread_1 == NULL)
    {
        printf("Create first thread problem \n");
        return 1;
    }

    /* sleep for 5 seconds **/
    Sleep(5 * 1000);

    /*Create thread 2 */
    Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);  
    if ( Handle_Of_Thread_2 == NULL)
    {
        printf("Create second thread problem \n");
        return 1;
    }

    // Sleep for 20 seconds
    Sleep(20 * 1000);

    printf("Out of the program \n");
    return 0;
}


int my_critical_section_code(HANDLE thread_handle)
{

#ifdef USE_MUTEX
    if(thread_handle == Handle_Of_Thread_1)
    {
        /* get the lock */
        WaitForSingleObject(ghMutex, INFINITE);
        printf("Thread 1 holding the mutex \n");
    }
#else
    /* get the semaphore */
    if(thread_handle == Handle_Of_Thread_1)
    {
        WaitForSingleObject(ghSemaphore, INFINITE);
        printf("Thread 1 holding semaphore \n");
    }
#endif

    if(thread_handle == Handle_Of_Thread_1)
    {
        /* sleep for 10 seconds */
        Sleep(10 * 1000);
#ifdef USE_MUTEX
        printf("Thread 1 about to release mutex \n");
#else
        printf("Thread 1 about to release semaphore \n");
#endif
    }
    else
    {
        /* sleep for 3 secconds */
        Sleep(3 * 1000);
    }

#ifdef USE_MUTEX
    /* release the lock*/
    if(!ReleaseMutex(ghMutex))
    {
        printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
    }
#else
    if (!ReleaseSemaphore(ghSemaphore,1,NULL) )      
    {
        printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
    }
#endif

    return 0;
}

DWORD WINAPI Thread_no_1( LPVOID lpParam ) 
{ 
    my_critical_section_code(Handle_Of_Thread_1);
    return 0;
}


DWORD WINAPI Thread_no_2( LPVOID lpParam ) 
{
    my_critical_section_code(Handle_Of_Thread_2);
    return 0;
}

Thực tế là semaphore cho phép bạn báo hiệu "nó được thực hiện bằng cách sử dụng tài nguyên", mặc dù nó không bao giờ sở hữu tài nguyên, khiến tôi nghĩ rằng có một sự kết hợp rất lỏng lẻo giữa việc sở hữu và báo hiệu trong trường hợp semaphores.


Nếu bạn đọc các câu trả lời khác, rõ ràng khái niệm "quyền sở hữu" chỉ có ý nghĩa với các trường hợp khác nhau, không phải là ngữ nghĩa. Semaphores có thể được sử dụng cho những thứ như một luồng cho các luồng khác biết rằng việc xử lý một khối dữ liệu đã được thực hiện; kết quả đã sẵn sàng để được đọc.
Peter Cordes

2

Mutex được sử dụng để bảo vệ mã và dữ liệu nhạy cảm, semaphore được sử dụng để đồng bộ hóa. Bạn cũng có thể sử dụng thực tế với bảo vệ mã nhạy cảm, nhưng có thể có rủi ro giải phóng sự bảo vệ của luồng khác bằng thao tác V.So Chính Sự khác biệt giữa bi-semaphore và mutex là quyền sở hữu. Ví dụ, bằng nhà vệ sinh, Mutex giống như người ta có thể vào nhà vệ sinh và khóa cửa, không ai khác có thể vào cho đến khi người đàn ông ra ngoài, bi-semaphore giống như người ta có thể vào nhà vệ sinh và khóa cửa, nhưng người khác có thể vào bằng cách yêu cầu quản trị viên mở cửa, thật nực cười.


2

Mutex

Mutexes thường được sử dụng để tuần tự truy cập vào một phần của mã đăng ký lại mà không thể được thực thi đồ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 truy cập vào phần đó để đợi cho đến khi luồng đầu tiên thoát khỏi phần đó. Việc sử dụng mutex là để bảo vệ tài nguyên được chia sẻ có thể gây nguy hiểm tác dụng phụ ngoài ý muốn. Bất kỳ hai nhiệm vụ RTOS nào hoạt động ở các mức độ ưu tiên khác nhau và phối hợp thông qua một mutex, tạo ra cơ hội đảo ngược ưu tiên . Mutex hoạt động trong không gian người dùng .

Semaphore

Semaphore là một cơ chế báo hiệu. Semaphore hạn chế số lượng người dùng đồng thời của một tài nguyên được chia sẻ lên đến số lượng tối đa. Các 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 chúng đã kết thúc bằng cách sử dụng tài nguyên (tăng semaphore). Nó cho phép số lượng luồng truy cập vào các tài nguyên được chia sẻ. Việc sử dụng chính xác một semaphore là để báo hiệu từ một nhiệm vụ này sang một nhiệm vụ khác. Cũng có thể được sử dụng để báo hiệu từ một thói quen dịch vụ ngắt (ISR) đến một nhiệm vụ. Báo hiệu một semaphore là một hành vi RTOS không chặn và do đó ISR an toàn. Bởi vì kỹ thuật này giúp loại bỏ nhu cầu dễ bị lỗi để vô hiệu hóa các ngắt ở cấp độ nhiệm vụ. Điều này hoạt động trong không gian kernel .


1

Câu trả lời có thể phụ thuộc vào hệ điều hành đích. Ví dụ: ít nhất một triển khai RTOS mà tôi quen thuộc sẽ cho phép nhiều hoạt động "nhận" tuần tự đối với một mutex OS duy nhất, miễn là tất cả chúng đều nằm trong cùng một bối cảnh luồng. Bội số phải được thay thế bằng số lần đặt bằng nhau trước khi một luồng khác sẽ được phép lấy mutex. Điều này khác với các ngữ nghĩa nhị phân, chỉ cho phép một lần lấy duy nhất tại một thời điểm, bất kể bối cảnh luồng.

Ý tưởng đằng sau loại mutex này là bạn bảo vệ một đối tượng bằng cách chỉ cho phép một bối cảnh duy nhất sửa đổi dữ liệu tại một thời điểm. Ngay cả khi luồng nhận được mutex và sau đó gọi một hàm sửa đổi thêm đối tượng (và nhận / đặt mutex bảo vệ xung quanh các hoạt động của chính nó), các hoạt động vẫn sẽ an toàn vì tất cả đều diễn ra trong một luồng.

{
    mutexGet();  // Other threads can no longer get the mutex.

    // Make changes to the protected object.
    // ...

    objectModify();  // Also gets/puts the mutex.  Only allowed from this thread context.

    // Make more changes to the protected object.
    // ...

    mutexPut();  // Finally allows other threads to get the mutex.
}

Tất nhiên, khi sử dụng tính năng này, bạn phải chắc chắn rằng tất cả các truy cập trong một luồng thực sự an toàn!

Tôi không chắc mức độ phổ biến của phương pháp này, hoặc liệu nó có áp dụng bên ngoài các hệ thống mà tôi quen thuộc không. Để biết ví dụ về loại mutex này, hãy xem ThreadX RTOS.


2
Loại mutex mà bạn đang nói đến được gọi là "mutex đệ quy" và nên tránh vì chúng chậm và có xu hướng thúc đẩy thiết kế xấu: (xem David Butenhof: zaval.org/resource/l Library / butenhof1.html )
gaspard

Đã đồng ý. Trên hệ điều hành cụ thể này, tôi sử dụng dịch vụ mutex nơi tôi muốn làm rõ rằng mã này là để "loại trừ lẫn nhau" và không tính tham chiếu, nhưng tôi không sử dụng tính năng đệ quy vì sợ làm xấu đi. Tuy nhiên, trong bối cảnh của câu hỏi, đây là một sự khác biệt quan trọng giữa một "mutex" và "semaphore nhị phân".
Casey Barker

1

Mutexes có quyền sở hữu, không giống như semaphores. Mặc dù bất kỳ luồng nào, trong phạm vi của một mutex, có thể có được một mutex đã được mở khóa và khóa truy cập vào cùng một phần quan trọng của mã, chỉ có luồng đã khóa một mutex mới mở khóa nó .


Quyền sở hữu là gì? Ý bạn là bối cảnh mua lại mutex chỉ có thể hủy bỏ nó. ??
Raulp

1

Như nhiều người ở đây đã đề cập, một mutex được sử dụng để bảo vệ một đoạn mã quan trọng (phần quan trọng của AKA.) Bạn sẽ có được mutex (khóa), nhập phần quan trọng và giải phóng mutex (mở khóa) tất cả trong cùng một luồng .

Trong khi sử dụng semaphore, bạn có thể tạo một luồng chờ trên semaphore (nói luồng A), cho đến khi một luồng khác (nói luồng B) hoàn thành bất kỳ nhiệm vụ nào, sau đó đặt Semaphore cho luồng A dừng chờ và tiếp tục nhiệm vụ của nó.


1

Giải pháp tốt nhất

Sự khác biệt duy nhất là

1.Mutex -> khóa và mở khóa thuộc quyền sở hữu của một chuỗi khóa mutex.

2.Semaphore -> Không có quyền sở hữu tức là; nếu một luồng gọi semwait (s) thì bất kỳ luồng nào khác có thể gọi sempost (s) để loại bỏ khóa.


1

MUTEX

Cho đến gần đây, khóa ngủ duy nhất trong kernel là semaphore. Hầu hết những người sử dụng semaphores đã tạo ra một semaphore với số lượng một và coi chúng như một khóa loại trừ lẫn nhau, một phiên bản ngủ của khóa xoay. Thật không may, semaphores khá chung chung và không áp đặt bất kỳ ràng buộc sử dụng. Điều này làm cho chúng hữu ích để quản lý quyền truy cập độc quyền trong các tình huống tối nghĩa, chẳng hạn như các điệu nhảy phức tạp giữa kernel và không gian người dùng. Nhưng điều đó cũng có nghĩa là việc khóa đơn giản sẽ khó thực hiện hơn và việc thiếu các quy tắc được thi hành khiến cho bất kỳ loại gỡ lỗi tự động hoặc thực thi ràng buộc nào đều không thể thực hiện được. Tìm kiếm một khóa ngủ đơn giản hơn, các nhà phát triển kernel đã giới thiệu mutex.Yes, như bạn đã quen với, đó là một cái tên khó hiểu. Chúng ta hãy làm rõ. Thuật ngữ này là một tên chung để chỉ bất kỳ khóa ngủ nào thực thi loại trừ lẫn nhau, chẳng hạn như một semaphore với số lượng sử dụng là một. Trong các nhân Linux gần đây, danh từ thích hợp mut mutex bây giờ cũng là một loại khóa ngủ cụ thể thực hiện loại trừ lẫn nhau. Đó là, một mutex là một mutex.

Sự đơn giản và hiệu quả của mutex đến từ các ràng buộc bổ sung mà nó áp đặt cho người dùng của nó hơn và hơn những gì semaphore yêu cầu. Không giống như semaphore, thực hiện hành vi cơ bản nhất theo thiết kế ban đầu của Dijkstra, mutex có trường hợp sử dụng chặt chẽ hơn, hẹp hơn: n Mỗi lần chỉ có một nhiệm vụ có thể giữ mutex. Đó là, số lượng sử dụng trên một mutex luôn luôn là một.

  1. Bất cứ ai khóa một mutex phải mở khóa nó. Đó là, bạn không thể khóa một mutex trong một bối cảnh và sau đó mở khóa nó trong một bối cảnh khác. Điều này có nghĩa là mutex không phù hợp để đồng bộ hóa phức tạp hơn giữa kernel và không gian người dùng. Tuy nhiên, hầu hết các trường hợp sử dụng, khóa và mở khóa sạch sẽ từ cùng một bối cảnh.
  2. Khóa đệ quy và mở khóa không được phép. Đó là, bạn không thể có được đệ quy cùng một mutex và bạn không thể mở khóa một mutex đã được mở khóa.
  3. Một quá trình không thể thoát trong khi giữ một mutex.
  4. Một mutex không thể có được bởi một trình xử lý ngắt hoặc nửa dưới, ngay cả với mutex_trylock ().
  5. Một mutex chỉ có thể được quản lý thông qua API chính thức: Nó phải được khởi tạo thông qua các phương thức được mô tả trong phần này và không thể được sao chép, khởi tạo bằng tay hoặc khởi tạo lại.

[1] Phát triển nhân Linux, phiên bản thứ ba Robert Love


1

Tôi nghĩ rằng hầu hết các câu trả lời ở đây đều khó hiểu, đặc biệt là những câu nói rằng mutex chỉ có thể được phát hành bởi quá trình giữ nó nhưng semaphore có thể được báo hiệu bởi quá trình ay. Dòng trên là loại mơ hồ về semaphore. Để hiểu chúng ta nên biết rằng có hai loại semaphore được gọi là semaphore và loại kia được gọi là semaphore nhị phân. Khi đếm semaphore, quyền truy cập vào n số tài nguyên trong đó n có thể được xác định trước khi sử dụng. Mỗi semaphore có một biến đếm, giữ cho số lượng tài nguyên được sử dụng, ban đầu, nó được đặt thành n. Mỗi quá trình muốn sử dụng một tài nguyên thực hiện một hoạt động Wait () trên semaphore (do đó làm giảm số lượng). Khi một quá trình giải phóng một tài nguyên, nó thực hiện một hoạt động phát hành () (tăng số lượng). Khi số đếm trở thành 0, tất cả các tài nguyên đang được sử dụng. Sau đó, quá trình đợi cho đến khi số đếm trở thành hơn 0. Bây giờ đây chỉ là quá trình giữ tài nguyên có thể tăng số lượng mà không quá trình nào khác có thể tăng số lượng, chỉ các quy trình giữ tài nguyên có thể tăng số lượng và quy trình chờ đợi semaphore kiểm tra lại và khi thấy tài nguyên có sẵn, nó sẽ giảm số lần nữa. Vì vậy, về mặt semaphore nhị phân, chỉ có quá trình giữ semaphore mới có thể tăng số lượng và số lượng vẫn bằng không cho đến khi nó ngừng sử dụng semaphore và tăng số lượng và quá trình khác có cơ hội truy cập vào semaphore. Bây giờ đây là chỉ bắt quá trình giữ tài nguyên có thể tăng số lượng, không có quy trình nào khác có thể tăng số lượng, chỉ các quy trình giữ tài nguyên có thể tăng số lượng và quá trình chờ semaphore kiểm tra lại và khi thấy tài nguyên có sẵn giảm số lượng một lần nữa. Vì vậy, về mặt semaphore nhị phân, chỉ có quá trình giữ semaphore mới có thể tăng số lượng và số lượng vẫn bằng không cho đến khi nó ngừng sử dụng semaphore và tăng số lượng và quá trình khác có cơ hội truy cập vào semaphore. Bây giờ đây là chỉ bắt quá trình giữ tài nguyên có thể tăng số lượng, không có quy trình nào khác có thể tăng số lượng, chỉ các quy trình giữ tài nguyên có thể tăng số lượng và quá trình chờ semaphore kiểm tra lại và khi thấy tài nguyên có sẵn giảm số lượng một lần nữa. Vì vậy, về mặt semaphore nhị phân, chỉ có quá trình giữ semaphore mới có thể tăng số lượng và số lượng vẫn bằng không cho đến khi nó ngừng sử dụng semaphore và tăng số lượng và quá trình khác có cơ hội truy cập vào semaphore.

Sự khác biệt chính giữa semaphore nhị phân và mutex là semaphore là một cơ chế báo hiệu và mutex là một cơ chế khóa, nhưng semaphore nhị phân dường như hoạt động như mutex tạo ra sự nhầm lẫn, nhưng cả hai đều là các khái niệm khác nhau phù hợp cho một loại công việc khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.