Khóa, mutex, semaphore có gì khác nhau?


439

Tôi đã nghe những từ này liên quan đến lập trình đồng thời, nhưng sự khác biệt giữa chúng là gì?



2
Lời giải thích tốt nhất mà tôi từng thấy: crystal.uta.edu/~ylei/cse6324/data/semaphore.pdf
expoter

Câu trả lời:


533

Khóa chỉ cho phép một luồng vào phần bị khóa và khóa không được chia sẻ với bất kỳ quy trình nào khác.

Một mutex giống như một khóa nhưng nó có thể là toàn hệ thống (được chia sẻ bởi nhiều quá trình).

Một semaphore thực hiện giống như một mutex nhưng cho phép x số luồng để nhập, ví dụ, điều này có thể được sử dụng để giới hạn số lượng cpu, io hoặc ram các tác vụ chuyên sâu chạy cùng lúc.

Đối với một bài viết chi tiết hơn về sự khác biệt giữa mutex và semaphore đọc tại đây .

Bạn cũng có khóa đọc / ghi cho phép không giới hạn số lượng người đọc hoặc 1 người viết tại bất kỳ thời điểm nào.


2
@mertinan Tôi không thể nói tôi từng nghe về nó, nhưng đây là những gì wikipedia nói "Latch (cơ sở dữ liệu), (khóa tương đối ngắn) trên cấu trúc dữ liệu hệ thống như một chỉ mục"
Peter

2
Màn hình cho phép chờ một điều kiện nhất định (ví dụ: khi khóa được giải phóng), "màn hình".
Dzmitry Lazerka

25
Một semaphore không giống như một mutex. Chúng được sử dụng rất khác nhau và cũng có các thuộc tính khác nhau (cụ thể là về quyền sở hữu). Xem ví dụ barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore để biết chi tiết
nanoquack

3
@nanoquack cứ thoải mái chỉnh sửa câu trả lời của tôi nếu bạn cảm thấy nó sai lệch hoặc không chính xác.
Peter

3
Để phân biệt rõ ràng hơn giữa mutex và semaphore, trong liên kết của nanoquack, Đoạn quan trọng là " 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. tác vụ sử dụng tài nguyên được chia sẻ mà nó bảo vệ. Ngược lại, các tác vụ sử dụng semaphores báo hiệu hoặc chờ đợi không phải cả hai. "
ToolmakerSteve

117

Có rất nhiều quan niệm sai lầm liên quan đến những từ này.

Đây là từ một bài viết trước ( https://stackoverflow.com/a/24582076/3163691 ) phù hợp tuyệt vời ở đây:

1) Phần quan trọng = Đối tượng người dùng được sử dụng để cho phép thực thi chỉ một luồng hoạt động từ nhiều luồng khác trong một quy trình . Các chủ đề không được chọn khác (@ có được đối tượng này) được đưa vào chế độ ngủ .

[Không có khả năng liên tiến trình, đối tượng rất nguyên thủy].

2) Mutex Semaphore (còn gọi là Mutex) = Đối tượng Kernel được sử dụng để cho phép thực thi chỉ một luồng hoạt động từ nhiều luồng khác, trong số các quy trình khác nhau . Các chủ đề không được chọn khác (@ có được đối tượng này) được đưa vào chế độ ngủ . Đối tượng này hỗ trợ quyền sở hữu luồng, thông báo chấm dứt luồng, đệ quy (nhiều cuộc gọi 'nhận' từ cùng một luồng) và 'tránh đảo ngược ưu tiên'.

[Khả năng xử lý, rất an toàn để sử dụng, một loại đối tượng đồng bộ hóa 'mức cao'].

3) Đếm Semaphore (còn gọi là Semaphore) = Đối tượng Kernel được sử dụng để cho phép thực thi một nhóm các luồng hoạt động từ nhiều người khác. Các chủ đề không được chọn khác (@ có được đối tượng này) được đưa vào chế độ ngủ .

[Tuy nhiên, khả năng xử lý của bộ xử lý không an toàn lắm vì nó thiếu các thuộc tính 'mutex': thông báo chấm dứt luồng, đệ quy?, 'Tránh đảo ngược ưu tiên'?, V.v.].

4) Và bây giờ, nói về 'spinlocks', đầu tiên một số định nghĩa:

Vùng quan trọng = Vùng nhớ được chia sẻ bởi 2 hoặc nhiều quá trình.

Khóa = Một biến có giá trị cho phép hoặc từ chối lối vào 'vùng quan trọng'. (Nó có thể được thực hiện như một 'cờ boolean' đơn giản).

Bận rộn chờ đợi = Kiểm tra liên tục một biến cho đến khi một số giá trị xuất hiện.

Cuối cùng:

Spin-lock (hay còn gọi là Spinlock) = Một khóa sử dụng chờ bận . (Việc mua khóa được thực hiện bởi xchg hoặc các hoạt động nguyên tử tương tự ).

[Không có luồng ngủ, chủ yếu chỉ được sử dụng ở cấp độ kernel. Không hiệu quả đối với mã cấp độ người dùng].

Như một bình luận cuối cùng, tôi không chắc nhưng tôi có thể đặt cược cho bạn một số tiền lớn mà 3 đối tượng đồng bộ hóa đầu tiên ở trên (# 1, # 2 và # 3) sử dụng con thú đơn giản này (# 4) như một phần của việc thực hiện chúng.

Chúc bạn ngày mới tốt lành!.

Người giới thiệu:

Khái niệm thời gian thực cho các hệ thống nhúng của Qing Li với Caroline Yao (Sách CMP).

-Hodern Operations Systems (thứ 3) của Andrew Tanenbaum (Pearson Education International).

-Các ứng dụng lập trình cho Microsoft Windows (thứ 4) của Jeffrey Richter (Dòng lập trình Microsoft).

Ngoài ra, bạn có thể xem qua: https://stackoverflow.com/a/24586804/3163691


1
Trên thực tế, phần quan trọng không phải là một đối tượng hạt nhân, do đó nhẹ hơn và không có khả năng đồng bộ hóa giữa các quy trình.
Vladislavs Burakovs

2
@ Vladislavs Burakovs: Bạn nói đúng! Tha thứ cho sự điều chỉnh của tôi. Tôi sẽ sửa nó vì sự gắn kết.
fante

Để phân biệt rõ ràng hơn giữa mutex và semaphore, như nanoquack đề cập ở nơi khác, hãy xem barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore - Đoạn văn chính là " Việc sử dụng chính xác một semaphore là để báo hiệu từ một tác vụ Đối với một nhiệm vụ khác có nghĩa là được thực hiện và phát hành, luôn theo thứ tự đó, bởi mỗi tác vụ sử dụng tài nguyên được chia sẻ mà nó bảo vệ. Ngược lại, các tác vụ sử dụng semaphores báo hiệu hoặc chờ đợi cả hai. "
ToolmakerSteve

Phỏng đoán các cơ chế khóa khác được xây dựng trên spinlock [không hiệu quả]: không có khả năng; AFAIK chỉ cần một số hoạt động nguyên tử cộng với hàng đợi ngủ. Kể cả trường hợp spinlock cần thiết bên trong hạt nhân, các giải pháp hiện đại giảm thiểu tác động của nó như được mô tả trong Wikipedia - spinlock - Lựa chọn thay thế - " .. sử dụng một cách tiếp cận lai gọi là 'thích nghi mutex' Ý tưởng là sử dụng một spinlock khi cố gắng truy cập vào một tài nguyên bị khóa bởi. một luồng hiện đang chạy, nhưng để ngủ nếu luồng hiện không chạy. (Cái sau luôn luôn là trên các hệ thống xử lý đơn.) "
ToolmakerSteve

@ToolmakerSteve, tôi dám cho bạn cung cấp 'giải pháp' mà không có 'spinlock' cho vấn đề 'va chạm' khi cố gắng 'chèn' ID luồng vào 'hàng đợi ngủ'. Dù sao, văn bản Wikipedia kết luận rằng một spinlock được sử dụng khi thực hiện !!!.
fante

27

Hầu hết các vấn đề có thể được giải quyết bằng cách sử dụng (i) chỉ khóa, (ii) chỉ là ngữ nghĩa, ... hoặc (iii) kết hợp cả hai! Như bạn có thể đã phát hiện ra, chúng rất giống nhau: cả hai đều ngăn chặn các điều kiện chủng tộc , cả hai hoạt động acquire()/ release()hoạt động, cả hai đều khiến 0 hoặc nhiều luồng bị chặn / nghi ngờ ... Thực sự, sự khác biệt quan trọng chỉ nằm ở cách chúng khóa và mở khóa .

  • Một khóa (hoặc mutex ) có hai trạng thái (0 hoặc 1). Nó có thể được mở khóa hoặc khóa . Chúng thường được sử dụng để đảm bảo chỉ có một luồng vào một phần quan trọng tại một thời điểm.
  • Một semaphore có nhiều trạng thái (0, 1, 2, ...). Nó có thể bị khóa (trạng thái 0) hoặc mở khóa (trạng thái 1, 2, 3, ...). Một hoặc nhiều semaphor thường được sử dụng cùng nhau để đảm bảo rằng chỉ một luồng vào một phần quan trọng chính xác khi số đơn vị của một số tài nguyên đã / chưa đạt đến một giá trị cụ thể (thông qua việc đếm xuống giá trị đó hoặc đếm đến giá trị đó ).

Đối với cả hai khóa / semaphores, cố gắng gọi acquire()trong khi nguyên thủy ở trạng thái 0 làm cho luồng gọi bị treo. Đối với khóa - các nỗ lực để có được khóa ở trạng thái 1 là thành công. Đối với semaphores - các nỗ lực để có được khóa ở các trạng thái {1, 2, 3, ...} đều thành công.

Đối với các khóa ở trạng thái 0, nếu cùng một luồng đã gọi trước đó acquire(), bây giờ gọi phát hành, thì việc phát hành thành công. Nếu một luồng khác đã thử điều này - đó là tùy thuộc vào việc triển khai / thư viện như những gì xảy ra (thường là bỏ qua nỗ lực hoặc lỗi được ném). Đối với semaphores ở trạng thái 0, bất kỳ luồng cũng có thể gọi phát hành và nó sẽ thành công (bất kể luồng nào được sử dụng trước đó để đặt semaphore ở trạng thái 0).

Từ các cuộc thảo luận trước, chúng ta có thể thấy rằng các khóa có khái niệm về chủ sở hữu (chủ đề duy nhất có thể gọi phát hành là chủ sở hữu), trong khi semaphores không có chủ sở hữu (bất kỳ chủ đề nào cũng có thể gọi phát hành trên semaphore).


Điều gây ra nhiều nhầm lẫn là, trong thực tế, chúng có nhiều biến thể của định nghĩa cấp cao này.

Các biến thể quan trọng cần xem xét :

  • Có gì nên acquire()/ release()được gọi là? - [Khác nhau ồ ạt ]
  • Khóa / semaphore của bạn có sử dụng "hàng đợi" hoặc "bộ" để ghi nhớ các chủ đề đang chờ không?
  • Khóa / semaphore của bạn có thể được chia sẻ với các chủ đề của các quá trình khác không?
  • Là khóa của bạn "reentrant"? - [Thường là có].
  • Là khóa của bạn "chặn / không chặn"? - [Thông thường không chặn được sử dụng làm khóa chặn (còn gọi là khóa xoay) gây ra sự chờ đợi bận rộn].
  • Làm thế nào để bạn đảm bảo các hoạt động là "nguyên tử"?

Những điều này phụ thuộc vào cuốn sách / giảng viên / ngôn ngữ / thư viện / môi trường của bạn.
Đây là một chuyến tham quan nhanh lưu ý cách một số ngôn ngữ trả lời các chi tiết này.


C, C ++ ( pthreads )

  • Một mutex được thực hiện thông qua pthread_mutex_t. Theo mặc định, chúng không thể được chia sẻ với bất kỳ quy trình nào khác ( PTHREAD_PROCESS_PRIVATE), tuy nhiên, mutex có một thuộc tính được gọi là chia sẻ . Khi được đặt, vì vậy mutex được chia sẻ giữa các process ( PTHREAD_PROCESS_SHARED).
  • Một cái khóa là điều tương tự như một mutex.
  • Một semaphore được thực hiện thông qua sem_t. Tương tự như mutexes, semaphores có thể được chia sẻ giữa các nhóm của nhiều tiến trình hoặc giữ riêng tư cho các luồng của một tiến trình đơn lẻ. Điều này phụ thuộc vào đối số chia sẻ được cung cấp cho sem_init.

python ( threading.py )

  • Một khóa ( threading.RLock) là chủ yếu giống như C / C ++ pthread_mutex_ts. Cả hai đều là reentrant . Điều này có nghĩa là chúng chỉ có thể được mở khóa bởi cùng một chủ đề đã khóa nó. Đó là trường hợp sem_tsemaphores, threading.Semaphoresemaphores và theading.Locklock không được reentrant - vì đó là trường hợp bất kỳ chủ đề nào có thể thực hiện mở khóa / xuống semaphore.
  • Một mutex giống như một khóa (thuật ngữ không được sử dụng thường xuyên trong python).
  • Một semaphore ( threading.Semaphore) hầu hết giống như sem_t. Mặc dù với sem_t, một hàng đợi id id được sử dụng để ghi nhớ thứ tự các luồng bị chặn khi cố khóa nó trong khi nó bị khóa. Khi một luồng mở ra một semaphore, luồng đầu tiên trong hàng đợi (nếu có) được chọn làm chủ sở hữu mới. Mã định danh luồng được đưa ra khỏi hàng đợi và semaphore sẽ bị khóa lại. Tuy nhiên, với threading.Semaphore, một tập hợp được sử dụng thay cho hàng đợi, vì vậy thứ tự các luồng bị chặn không được lưu trữ - bất kỳ luồng nào trong tập hợp có thể được chọn làm chủ sở hữu tiếp theo.

Java ( java.util.conc hiện )

  • Một khóa ( java.util.concurrent.ReentrantLock) là chủ yếu giống như C / C ++ pthread_mutex_t's, và Python threading.RLockở chỗ nó cũng thực hiện một khóa reentrant. Chia sẻ khóa giữa các quy trình khó hơn trong Java do JVM đóng vai trò trung gian. Nếu một chủ đề cố gắng mở khóa một khóa mà nó không sở hữu, một chủ đề IllegalMonitorStateExceptionsẽ bị ném.
  • Một mutex giống như một khóa (thuật ngữ này không được sử dụng thường xuyên trong Java).
  • Một semaphore ( java.util.concurrent.Semaphore) chủ yếu giống như sem_tthreading.Semaphore. Hàm tạo cho các semaphores Java chấp nhận một tham số boolean công bằng kiểm soát việc sử dụng một tập hợp (sai) hay hàng đợi (true) để lưu trữ các luồng chờ.

Về lý thuyết, semaphores thường được thảo luận, nhưng trong thực tế, semaphores không được sử dụng nhiều. Một semaphore chỉ giữ trạng thái của một số nguyên, do đó, nó thường không linh hoạt và nhiều thứ cần thiết cùng một lúc - gây khó khăn trong việc hiểu mã. Ngoài ra, thực tế là bất kỳ chủ đề có thể phát hành một semaphore đôi khi không mong muốn. Thay vào đó, nhiều nguyên tắc / trừu tượng đồng bộ hóa hướng đối tượng / mức độ cao hơn như "biến điều kiện" và "màn hình" được sử dụng thay thế.


22

Hãy xem Hướng dẫn đa luồng của John Kopplin.

Trong phần Đồng bộ hóa giữa các Chủ đề , anh giải thích sự khác biệt giữa các sự kiện, khóa, mutex, semaphore, bộ đếm thời gian chờ

Một mutex chỉ có thể được sở hữu bởi một luồng tại một thời điểm, cho phép các luồng phối hợp truy cập loại trừ lẫn nhau vào một tài nguyên được chia sẻ

Các đối tượng phần quan trọng cung cấp đồng bộ hóa tương tự như đối tượng được cung cấp bởi các đối tượng mutex, ngoại trừ các đối tượng phần quan trọng chỉ có thể được sử dụng bởi các luồng của một quy trình duy nhất

Một sự khác biệt khác giữa một mutex và một phần quan trọng là nếu đối tượng của phần quan trọng hiện đang được sở hữu bởi một luồng khác, EnterCriticalSection() chờ đợi vô thời hạn quyền sở hữu trong khi WaitForSingleObject(), được sử dụng với mutex, cho phép bạn chỉ định thời gian chờ

Một semaphore duy trì số đếm giữa 0 và một số giá trị tối đa, giới hạn số lượng luồng đang truy cập đồng thời một tài nguyên được chia sẻ.


15

Tôi sẽ cố gắng che nó bằng các ví dụ:

Khóa: Một ví dụ mà bạn sẽ sử dụng locksẽ là một từ điển được chia sẻ trong đó các mục (phải có khóa duy nhất) được thêm vào.
Khóa sẽ đảm bảo rằng một luồng không nhập vào cơ chế mã đang kiểm tra mục có trong từ điển trong khi một luồng khác (nằm trong phần quan trọng) đã vượt qua kiểm tra này và đang thêm mục. Nếu một luồng khác cố gắng nhập mã bị khóa, nó sẽ đợi (bị chặn) cho đến khi đối tượng được giải phóng.

private static readonly Object obj = new Object();

lock (obj) //after object is locked no thread can come in and insert item into dictionary on a different thread right before other thread passed the check...
{
    if (!sharedDict.ContainsKey(key))
    {
        sharedDict.Add(item);
    }
}

Semaphore: Giả sử bạn có một nhóm kết nối, sau đó một luồng có thể dự trữ một phần tử trong nhóm bằng cách đợi semaphore nhận được kết nối. Sau đó, nó sử dụng kết nối và khi công việc hoàn thành sẽ giải phóng kết nối bằng cách phát hành semaphore.

Ví dụ mã mà tôi yêu thích là một trong những bouncer được đưa ra bởi @Patric - đây là:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TheNightclub
{
    public class Program
    {
        public static Semaphore Bouncer { get; set; }

        public static void Main(string[] args)
        {
            // Create the semaphore with 3 slots, where 3 are available.
            Bouncer = new Semaphore(3, 3);

            // Open the nightclub.
            OpenNightclub();
        }

        public static void OpenNightclub()
        {
            for (int i = 1; i <= 50; i++)
            {
                // Let each guest enter on an own thread.
                Thread thread = new Thread(new ParameterizedThreadStart(Guest));
                thread.Start(i);
            }
        }

        public static void Guest(object args)
        {
            // Wait to enter the nightclub (a semaphore to be released).
            Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
            Bouncer.WaitOne();          

            // Do some dancing.
            Console.WriteLine("Guest {0} is doing some dancing.", args);
            Thread.Sleep(500);

            // Let one guest out (release one semaphore).
            Console.WriteLine("Guest {0} is leaving the nightclub.", args);
            Bouncer.Release(1);
        }
    }
}

Mutex Nó là khá nhiều Semaphore(1,1)và thường được sử dụng trên toàn cầu (ứng dụng rộng rãi nếu không được cho locklà phù hợp hơn). Người ta sẽ sử dụng toàn cục Mutexkhi xóa nút khỏi danh sách có thể truy cập toàn cầu (điều cuối cùng bạn muốn một luồng khác thực hiện điều gì đó trong khi bạn đang xóa nút). Khi bạn có được Mutexnếu các luồng khác nhau cố gắng thu được giống nhau, Mutexnó sẽ được chuyển sang chế độ ngủ cho đến khi chủ đề CÙNG thu được các Mutexbản phát hành.

Ví dụ điển hình về việc tạo mutex toàn cầu là bởi @deepee

class SingleGlobalInstance : IDisposable
{
    public bool hasHandle = false;
    Mutex mutex;

    private void InitMutex()
    {
        string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
        string mutexId = string.Format("Global\\{{{0}}}", appGuid);
        mutex = new Mutex(false, mutexId);

        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);
    }

    public SingleGlobalInstance(int timeOut)
    {
        InitMutex();
        try
        {
            if(timeOut < 0)
                hasHandle = mutex.WaitOne(Timeout.Infinite, false);
            else
                hasHandle = mutex.WaitOne(timeOut, false);

            if (hasHandle == false)
                throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
        }
        catch (AbandonedMutexException)
        {
            hasHandle = true;
        }
    }


    public void Dispose()
    {
        if (mutex != null)
        {
            if (hasHandle)
                mutex.ReleaseMutex();
            mutex.Dispose();
        }
    }
}

sau đó sử dụng như:

using (new SingleGlobalInstance(1000)) //1000ms timeout on global lock
{
    //Only 1 of these runs at a time
    GlobalNodeList.Remove(node)
}

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.


8

Wikipedia có một phần tuyệt vời về sự khác biệt giữa Semaphores và Mutexes :

Một mutex về cơ bản là giống như một semaphore nhị phân và đôi khi sử dụng cùng một triển khai cơ bản. Sự khác biệt giữa chúng là:

Mutexes có một khái niệm về một chủ sở hữu, đó là quá trình khóa mutex. Chỉ có quá trình khóa mutex mới có thể mở khóa nó. Ngược lại, một semaphore không có khái niệm về chủ sở hữu. Bất kỳ quá trình có thể mở khóa một semaphore.

Không giống như semaphores, mutexes cung cấp an toàn đảo ngược ưu tiên. Vì mutex biết chủ sở hữu hiện tại của nó, có thể thúc đẩy mức độ ưu tiên của chủ sở hữu bất cứ khi nào một nhiệm vụ ưu tiên cao hơn bắt đầu chờ đợi trên mutex.

Mutexes cũng cung cấp an toàn xóa, trong đó quá trình giữ mutex có thể vô tình bị xóa. Semaphores không cung cấp điều này.


5

Tôi hiểu rằng một mutex chỉ được sử dụng trong một quy trình duy nhất, nhưng trên nhiều luồng của nó, trong khi một semaphore có thể được sử dụng trên nhiều quy trình và trên các chuỗi chủ đề tương ứng của chúng.

Ngoài ra, một mutex là nhị phân (nó bị khóa hoặc mở khóa), trong khi một semaphore có khái niệm đếm hoặc một hàng đợi nhiều hơn một yêu cầu khóa và mở khóa.

Ai đó có thể xác minh lời giải thích của tôi? Tôi đang nói về ngữ cảnh của Linux, cụ thể là Red Hat Enterprise Linux phiên bản 6 (RHEL), sử dụng kernel 2.6.32.


3
Bây giờ điều này có thể khác nhau trong các hệ điều hành khác nhau nhưng trong các cửa sổ, Mutex có thể được sử dụng bởi nhiều quy trình ít nhất là đối tượng Mutex .net ..
Peter

2
stackoverflow.com/questions/9389730/ '"Chủ đề trong cùng một quy trình hoặc trong các quy trình khác có thể chia sẻ các mutexes." vì vậy không có một mutex phải không được quy trình cụ thể.
Peter

3

Sử dụng lập trình C trên một biến thể Linux làm ví dụ cơ bản.

Khóa:

• Thường là một nhị phân cấu trúc rất đơn giản trong hoạt động hoặc bị khóa hoặc mở khóa

• Không có khái niệm về quyền sở hữu chủ đề, ưu tiên, trình tự, vv

• Thường là khóa xoay trong đó chỉ liên tục kiểm tra tính khả dụng của khóa.

• Thường dựa vào các hoạt động nguyên tử, ví dụ: Thử và đặt, so sánh và trao đổi, tìm nạp và thêm, v.v.

• Thường yêu cầu hỗ trợ phần cứng cho hoạt động nguyên tử.

Khóa tệp:

• Thường được sử dụng để phối hợp truy cập vào một tệp thông qua nhiều quy trình.

• Nhiều quy trình có thể giữ khóa đọc tuy nhiên khi bất kỳ quy trình nào giữ khóa ghi thì không có quy trình nào khác được phép có được khóa đọc hoặc ghi.

• Ví dụ: đàn, fcntl, v.v.

Đột biến:

• Các lệnh gọi hàm Mutex thường hoạt động trong không gian kernel và dẫn đến các cuộc gọi hệ thống.

• Nó sử dụng khái niệm quyền sở hữu. Chỉ có chủ đề hiện đang giữ mutex có thể mở khóa nó.

• Mutex không được đệ quy (Ngoại lệ: PTHREAD_MUTEX_RECURSIVE).

• Thường được sử dụng trong Hiệp hội với Biến điều kiện và được chuyển làm đối số cho ví dụ: pthread_cond_signal, pthread_cond_wait, v.v.

• Một số hệ thống UNIX cho phép mutex được sử dụng bởi nhiều quy trình mặc dù điều này có thể không được thi hành trên tất cả các hệ thống.

Semaphore:

• Đây là một số nguyên duy trì hạt nhân có giá trị không được phép giảm xuống dưới 0.

• Nó có thể được sử dụng để đồng bộ hóa các quy trình.

• Giá trị của semaphore có thể được đặt thành giá trị lớn hơn 1 trong trường hợp đó giá trị thường cho biết số lượng tài nguyên có sẵn.

• Một semaphore có giá trị được giới hạn ở 1 và 0 được gọi là một semaphore nhị phân.


0

Supporting ownership, maximum number of processes share lockmaximum number of allowed processes/threads in critical sectionba yếu tố chính mà xác định tên / loại của đối tượng đồng thời với tên chung của lock. Vì giá trị của các yếu tố này là nhị phân (có hai trạng thái), chúng tôi có thể tóm tắt chúng trong bảng giống như sự thật 3 * 8.

  • X (Hỗ trợ quyền sở hữu?): Không (0) / có (1)
  • Y (#shishing quy trình):> 1 (∞) / 1
  • Z (# process / thread trong CA):> 1 (∞) / 1

  X   Y   Z          Name
 --- --- --- ------------------------
  0   ∞   ∞   Semaphore              
  0   ∞   1   Binary Semaphore       
  0   1   ∞   SemaphoreSlim          
  0   1   1   Binary SemaphoreSlim(?)
  1   ∞   ∞   Recursive-Mutex(?)     
  1   ∞   1   Mutex                  
  1   1   ∞   N/A(?)                 
  1   1   1   Lock/Monitor           

Vui lòng chỉnh sửa hoặc mở rộng bảng này, tôi đã đăng nó dưới dạng bảng ascii để có thể chỉnh sửa :)

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.