二进制信号量和互斥量之间的区别

2023-05-16

二进制信号量和互斥量之间是否有任何区别,或者它们基本相同?


#1楼

它们的同步语义非常不同:

  • 互斥锁允许序列化对给定资源的访问,即多个线程一次等待一个锁,并且如前所述,该线程拥有该锁直到完成: 只有这个特定的线程才能将其解锁。
  • 二进制信号量是一个值为0和1的计数器,一个任务在其上阻塞,直到任何任务执行sem_post为止。 信号量通告资源可用,并且它提供了一种机制,等待信号通知资源可用。

因此,可以将互斥锁看作是从一个任务传递到另一个任务的令牌,而将信号量看作是流量红灯( 表示有人可以继续进行操作)。


#2楼

http://www.geeksforgeeks.org/archives/9102详细讨论。

Mutex是一种锁定机制,用于同步对资源的访问。 Semaphore是信号机制。

如果他/她想使用二进制信号量代替互斥量,则取决于程序员。


#3楼

显然,您可以使用互斥锁将数据锁定在一个线程中,同时另一个线程可以访问该数据。 假设您刚刚调用了lock()并正在访问数据。 这意味着您不希望任何其他线程(或相同线程代码的另一个实例)访问由相同互斥锁锁定的相同数据。 也就是说,如果在不同的线程实例上执行的是相同的线程代码,则会命中该锁,那么lock()应该在那里阻塞控制流。 这适用于使用不同线程代码的线程,该线程代码也正在访问相同的数据,并且也被相同的互斥锁锁定。 在这种情况下,您仍处于访问数据的过程中,并且可能要花15秒钟才能达到互斥锁解锁(这样,在互斥锁中被阻塞的另一个线程将解除阻塞,并使控件能够访问数据)。 您是否不惜一切代价允许另一个线程仅解锁同一个互斥锁,然后又允许互斥锁中已在等待(阻塞)的线程取消阻塞并访问数据? 希望你明白我在这里说的话吗? 根据一致同意的通用定义!,

  • 使用“互斥体”不会发生这种情况。 没有其他线程可以解锁您的线程中的锁
  • 使用“二进制信号量”会发生这种情况。 任何其他线程都可以解锁您线程中的锁

因此,如果您非常在意使用二进制信号量而不是互斥量,那么在“确定”锁定和解锁范围时应格外小心。 我的意思是,碰到每个锁的每个控制流都应该打一个解锁调用,也不应有任何“首次解锁”,而应该始终是“首次锁定”。


#4楼

关于该主题的不错的文章:

  • MUTEXVS。 SEMAPHORES –第1部分:SEMAPHORES
  • MUTEXVS。 SEMAPHORES –第2部分:MUTEX
  • MUTEXVS。 SEMAPHORES –第3部分(最后部分):互斥问题

从第2部分开始:

互斥锁与二进制信号量的原理相似,但有一个明显的区别:所有权原理。 所有权是一个简单的概念,当任务锁定(获取)互斥锁时,它只能解锁(释放)它。 如果任务试图解锁一个尚未锁定的互斥锁(因此不拥有),则会遇到错误情况,最重要的是,互斥锁不会解锁。 如果互斥对象不具有所有权,则与其所谓的无关,它不是互斥体。


#5楼

Mutex用于保护敏感代码和数据,信号量用于同步。您也可以与保护敏感代码一起实际使用,但是可能存在通过操作V释放其他线程的保护的风险。双信号量和互斥量之间的区别是所有权。例如,在洗手间,互斥量就像一个人可以进入马桶并锁上门,直到有人下车,其他人才能进入;双信号量就像一个人可以进入厕所并锁上门,但是其他人可以通过要求管理员打开门来进入,这很荒谬。


#6楼

互斥锁用于“锁定机制”。 一次一个进程可以使用共享资源

信号量用于“信号机制”,例如“我已经完成,现在可以继续”


#7楼

  • 根据定义, 互斥锁用于序列化对不能由多个线程同时执行的可重入代码段的访问。

  • 根据定义, 信号量将共享资源的同时用户数限制为最大数量

  • 信号量可以是互斥量,但互斥量永远不能是信号量。 这只是意味着二进制信号量可以用作互斥量,但是互斥量永远不能表现出信号量的功能。

  • 信号量和Mutex(至少是最新的内核)本质上都是非递归的。
  • 没有人拥有信号灯,而Mutex是拥有的,而所有者则对此负有责任。 从调试的角度来看,这是一个重要的区别。
  • 如果是Mutex,则拥有Mutex的线程负责释放它。 但是,在信号量的情况下,不需要此条件。 任何其他线程都可以通过使用smps(function.e_ot)发出信号以释放信号量

  • 对开发人员来说另一个重要的区别是,信号量是系统范围的,除非以其他方式进行清理,否则它们将以文件形式保留在文件系统中。 互斥锁是整个进程的,并在进程退出时自动清除。

  • 信号量的性质使得可以在同步相关和不相关的进程以及线程之间使用它们。 Mutex仅可用于线程之间以及最多相关进程之间的同步(最新内核的pthread实现具有允许在相关进程之间使用Mutex的功能)。
  • 根据内核文档,与信号量相比,互斥量更轻。 这意味着与使用Mutex的程序相比,使用信号量的程序具有更高的内存占用量。
  • 从使用的角度来看,与信号量相比,互斥体的语义更简单。

#8楼

在浏览完上述帖子后,这个概念对我很清楚。 但是还有一些挥之不去的问题。 所以,我写了这段小代码。

当我们尝试不使用信号灯时,它就会通过。 但是,当您尝试不使用互斥体而给出互斥体时,它将失败。 我在Windows平台上对此进行了测试。 启用USE_MUTEX以使用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;
}

即使信号量从未拥有该资源,它也可以让您发出信号“使用资源完成操作”这一事实使我认为,在信号量的情况下,拥有和信号之间存在非常松散的耦合。


#9楼

由于以上答案都不能消除混乱,因此以下是我的困惑。

严格来说, 互斥锁是一种锁定机制,用于同步对资源的访问。 只有一个任务(可以是基于OS抽象的线程或进程)可以获取互斥量。 这意味着将有与互斥锁关联的所有权,只有所有者才能释放锁(互斥锁)。

信号量是信号机制 (“我做完了,您可以进行”这种信号)。 例如,如果您正在手机上收听歌曲(假设它是一项任务),并且您的朋友同时打给您,则将触发一个中断,中断服务程序(ISR)将在此信号通知呼叫处理任务唤醒。

资料来源: http : //www.geeksforgeeks.org/mutex-vs-semaphore/


#10楼

在Windows上,互斥量和二进制信号量之间有两个区别:

  1. 互斥锁只能由具有所有权的线程释放,即先前称为Wait函数的线程(或在创建该线程时拥有所有权的线程)。 信号量可以由任何线程释放。

  2. 线程可以在互斥对象上反复调用wait函数而不会阻塞。 但是,如果您在二进制信号量上调用了两次wait函数而没有释放它们之间的信号量,则该线程将阻塞。


#11楼

神话:

几篇文章说“二进制信号量和互斥量相同”或“值为1的信号量是互斥量”,但基本区别是Mutex只能由获取它的线程释放,而您可以从任何其他线程发出信号量

关键点:

•一个线程可以获取多个锁(Mutex)。

•互斥锁只能是递归互斥锁才能多次锁定,此处互斥锁的锁定和解锁应该相同

•如果已经锁定了互斥锁的线程再次尝试锁定该互斥锁,它将进入该互斥锁的等待列表,从而导致死锁。

•二进制信号量和互斥量相似但不相同。

•由于与之相关的保护协议,Mutex的运行成本很高。

•互斥锁的主要目的是实现原子访问或锁定资源


#12楼

尽管互斥量和信号量被用作同步原语,但它们之间还是有很大的区别。 对于互斥锁,只有锁定或获取了互斥锁的线程才能对其进行解锁。 对于信号量,等待信号量的线程可以由其他线程发出信号。 一些操作系统支持在进程之间使用互斥量和信号量。 通常,用法是在共享内存中创建。


#13楼

修改后的问题是-A互斥锁与“ Linux”中的“二进制”信号量有什么区别?

答案:以下是区别– i)范围–互斥锁的范围在创建它的进程地址空间内,并用于线程同步。 信号量可以在整个过程空间中使用,因此可以用于进程间同步。

ii)Mutex比信号量轻巧且速度更快。 Futex甚至更快。

iii)互斥量可以被同一线程多次成功获取,但前提是它必须释放相同的次数。 尝试获取的其他线程将阻塞。 而在信号量的情况下,如果相同的过程尝试再次获取它,则它将阻塞,因为它只能被获取一次。


#14楼

Binary Semaphore和Mutex之间的区别:所有权: 甚至可以从非当前所有者发出信号(张贴)。 这意味着尽管您不是所有者,但您可以从任何其他线程中进行发布。

信号量是一个正在使用的公共财产,可以由非所有者线程简单地发布。 请用粗体字母标记出此差异,这很重要。


#15楼

Mutex可以阻止关键区域,而Semaphore则可以实现计数。


#16楼

从理论上讲,它们在语义上没有什么不同。 您可以使用信号量来实现互斥,反之亦然(请参见此处的示例)。 实际上,实现方式有所不同,它们提供的服务略有不同。

实际的区别(就围绕它们的系统服务而言)是,互斥锁的实现旨在成为一种更轻量级的同步机制。 用甲骨文来说,互斥锁称为闩锁 ,信号量称为waits 。

在最低级别上,他们使用某种原子测试和设置机制。 这将读取内存位置的当前值,计算某种条件的值,并在一条不能中断的指令中写出该位置的值。 这意味着您可以获取一个互斥锁并进行测试,以查看是否有人在您之前拥有它。

典型的互斥锁实现有一个进程或线程执行测试设置指令并评估是否有其他任何东西设置了互斥锁。 这里的关键点是与调度程序之间没有交互,因此我们不知道(也不在乎)谁设置了锁定。 然后,我们要么放弃时间片,然后在重新计划任务时重试它,要么执行自旋锁 。 自旋锁是一种类似以下的算法:

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.

当我们执行完受保护的代码(称为关键部分 )后,我们只需将互斥锁值设置为零或任何表示“清除”的值即可。 如果有多个任务试图获取互斥锁,则在释放互斥锁之后碰巧计划的下一个任务将可以访问该资源。 通常,您将使用互斥锁来控制同步资源,其中仅在非常短的时间内才需要独占访问,通常可以对共享数据结构进行更新。

信号量是一个同步的数据结构(通常使用互斥锁),它具有一个计数和一些系统调用包装程序,它们与调度程序进行交互的深度比互斥锁库要深一些。 信号量会增加和减少,并用于阻止任务,直到准备好其他东西为止。 有关此示例,请参阅生产者/消费者问题 。 信号量被初始化为某个值-二进制信号量只是信号量被初始化为1的特例。发给信号量具有唤醒等待过程的效果。

基本的信号量算法如下所示:

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

在二进制信号量的情况下,两者之间的主要实际差异是围绕实际数据结构的系统服务的性质。

编辑:正如evan正确指出的那样,自旋锁会降低单处理器计算机的速度。 您只能在多处理器盒上使用自旋锁,因为在单处理器上,持有互斥锁的进程永远不会在其他任务运行时将其重置。 自旋锁仅在多处理器体系结构上有用。


#17楼

互斥量和二进制信号量的用法相同,但实际上它们是不同的。

如果是互斥锁,只有锁定它的线程才能解锁它。 如果有任何其他线程来锁定它,它将等待。

如果是信号灯,情况并非如此。 信号量不与特定线程ID捆绑在一起。


#18楼

厕所的例子很有趣:

互斥体:

是上厕所的钥匙。 当时,一个人可以拥有钥匙-上厕所。 完成后,此人将密钥释​​放(释放)给队列中的下一个人。

正式地:“ Mutexe通常用于序列化不能由多个线程同时执行的可重入代码段的访问。互斥对象仅允许一个线程进入受控段,从而迫使其他试图获取访问权限的线程该部分等待,直到第一个线程从该部分退出。” 参考:Symbian开发人员库

(互斥量实际上是值为1的信号量。)

信号:

是免费的相同马桶钥匙的数量。 例如,假设我们有四个具有相同锁和钥匙的卫生间。 信号量计数(按键计数)在开始时设置为4(所有四个洗手间都是免费的),然后计数值随着人们的进入而递减。如果所有洗手间都已满,即。 没有剩余的可用键,信号量为0。 一个人离开洗手间,信号量增加到1(一个自由键),并交给队列中的下一个人。

正式地:“信号量将共享资源的并发用户数限制为最大数量。线程可以请求访问该资源(减少信号量),并且可以发出信号,表明他们已经使用完资源(增加信号量)。 ” 参考:Symbian开发人员库


#19楼

除了互斥对象具有所有者这一事实之外,还可以针对不同的用法优化这两个对象。 互斥对象只能保留很短的时间。 违反此规定可能会导致性能下降和调度不公。 例如,即使另一个线程已被阻塞,正在运行的线程也可能被允许获取互斥量。 信号量可以提供更多的公平性,或者可以使用多个条件变量来强制公平性。


#20楼

正如这里的许多人所提到的,互斥锁用于保护关键代码段(AKA关键段)。您将在同一线程中获取互斥锁(锁定),进入关键段并释放互斥锁(解锁)。

在使用信号量时,您可以让一个线程在信号量(例如线程A)上等待,直到另一个线程(例如线程B)完成任何任务,然后为线程A设置信号量以停止等待并继续其任务。


#21楼

虽然可以将二进制信号量用作互斥锁,但是互斥锁是一种更特定的用例,因为只有锁定互斥锁的过程才可以对其进行解锁。 此所有权约束使得可以针对以下情况提供保护:

  • 意外释放
  • 递归死锁
  • 任务死亡僵局

这些约束并不总是存在,因为它们会降低速度。 在开发代码期间,您可以临时启用这些检查。

例如,您可以在互斥锁中启用错误检查属性。 如果尝试两次锁定同一互斥锁,则错误检查互斥锁会返回EDEADLK如果解锁非您自己的互斥锁,则会EPERM

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);

初始化后,我们可以将这些检查放入我们的代码中,如下所示:

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

#22楼

Mutex:假设我们有关键部分线程T1要访问它,则它遵循以下步骤。 T1:

  1. 使用关键部分
  2. 开锁

二进制信号量:它基于信令等待和信号。 等待将“ s”值减小一,通常将“ s”值初始化为值“ 1”,信号将“ s”值增大一。 如果“ s”值为1表示没有人使用临界区,而值为0则表示正在使用临界区。 假设线程T2使用的是关键部分,则遵循以下步骤。 T2:

  1. wait(s)//最初的值是在调用wait之后为1,其值减小了1,即0
  2. 使用关键部分
  3. 信号//现在s的值增加并且变为1

Mutex和Binary信号量之间的主要区别在于Mutext中,如果线程锁定了关键部分,则它必须解锁关键部分,没有其他线程可以解锁它,但是对于Binary信号量,如果一个线程使用wait(s)函数锁定了关键部分,则value的s变为“ 0”,直到“ s”的值变为1之前没有人可以访问它,但是假设其他线程调用信号,则“ s”的值变为1,并且允许其他函数使用临界区。 因此,在二进制信号量线程中没有所有权。


#23楼

互斥锁控制对单个共享资源的访问。 它提供操作来获取()访问该资源并在完成后释放()

信号量控制对共享资源池的访问。 它向Wait()提供操作,直到池中的资源之一变为可用为止;向Signal()提供操作时将其返回给池。

当信号量保护的资源数量大于1时,称为计数信号量 。 当它控制一个资源时,它称为Boolean Semaphore 。 布尔信号量等效于互斥量。

因此,信号量是比互斥对象更高级别的抽象。 互斥量可以使用信号量来实现,但不能相反。


#24楼

“二进制信号量”是一种使用诸如“ mutex”之类的“信号量”的编程语言。 显然有两个很大的不同:

  1. 您称呼每个人的方式。

  2. “标识符”的最大长度。


#25楼

互斥体

互斥锁通常用于序列化对不能由多个线程同时执行的可重入代码段的访问。 互斥对象仅允许一个线程进入受控部分,从而迫使试图访问该部分的其他线程要等到第一个线程退出该部分为止。正确使用互斥对象是为了保护共享资源,可能会有危险。意外的副作用。 以不同优先级运行并通过互斥体进行协调的任何两个RTOS任务都会为优先级倒置创造机会。 Mutex在用户空间中工作

信号

信号量是一种信号机制。 信号量将共享资源的同时用户数限制为最大数量。 线程可以请求对资源的访问(减少信号量),并且可以发出信号,表明它们已经完成了对资源的使用(增加信号量)。 它允许多个线程访问共享资源。信号量的正确用法是用于将信号从一个任务发送到另一任务,也可以将信号量用于从中断服务程序 (ISR)信号发送到任务。 发信号量信号是一种无阻塞的RTOS行为,因此具有ISR安全性。 由于此技术消除了在任务级别禁用中断的容易出错的需求,因此可以在内核空间中使用


#26楼

基本问题是并发性。 有不止一个控制流。 考虑使用共享内存的两个进程。 现在,一次只有一个进程可以访问共享内存。 如果一次有多个进程访问共享内存,则共享内存的内容将被破坏。 就像铁轨一样。 只有一列火车可以在其上行驶,否则会发生事故,因此存在一种信号机制,驾驶员可以进行检查。 如果信号为绿色,则火车可以行驶;如果信号为红色,则必须等待使用轨道。 类似地,在共享内存的情况下,有一个二进制信号量。 如果信号量为1,则进程将其获取(将其设置为0)并继续进行访问。 如果信号量为0,则过程等待。 二进制信号量必须提供的功能是互斥(简称互斥),因此许多并发实体(进程或线程)中只有一个相互排斥其他实体。 我们拥有计数信号量的优势,这有助于同步资源的多个实例。

互斥是信号量提供的基本功能。 现在,在线程的上下文中,我们可能有不同的名称和语法。 但是基本概念是相同的:如何在并发编程中保持代码和数据的完整性。 在我看来,所有权和相关检查之类的东西是实现提供的改进。


#27楼

  • 互斥锁只能由已获取 互斥锁 的线程释放。
  • 二进制信号量可以由任何线程 (或进程)发出信号。

因此,信号量更适合于一些同步问题,例如生产者-消费者。

在Windows上,二进制信号量比互斥体更像事件对象。


#28楼

答案可能取决于目标操作系统。 例如,至少一个我熟悉的RTOS实现将允许对单个OS互斥锁进行多个顺序的“获取”操作,只要它们都来自同一线程上下文中即可。 在允许另一个线程获取互斥体之前,必须用相等数量的puts替换多个get。 这不同于二进制信号量,二进制信号量一次仅允许一次获取,而与线程上下文无关。

这种互斥量背后的想法是,通过仅允许单个上下文一次修改数据来保护对象。 即使线程获取了互斥锁,然后调用了进一步修改对象的函数(并使其自身的操作获取/放置了保护器互斥锁),这些操作仍应是安全的,因为它们都在单个线程下发生。

{
    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.
}

当然,使用此功能时,必须确保单个线程内的所有访问确实是安全的!

我不确定这种方法有多普遍,或者它是否适用于我所熟悉的系统之外。 有关此类互斥锁的示例,请参见ThreadX RTOS。


#29楼

他们不是一回事。 它们用于不同目的!
虽然两种类型的信号量都具有完整/空状态并使用相同的API,但它们的用法却大不相同。

互斥信号灯
互斥信号量用于保护共享资源(数据结构,文件等)。

Mutex信号量由执行该任务的任务“拥有”。 如果任务B尝试给任务A当前持有的互斥锁赋值,则任务B的调用将返回错误并失败。

互斥对象始终使用以下顺序:


- SemTake
  - Critical Section
  - SemGive  

这是一个简单的示例:


Thread A                     Thread B
   Take Mutex
     access data
     ...                        Take Mutex  <== Will block
     ...
   Give Mutex                     access data  <== Unblocks
                                  ...
                                Give Mutex  

二进制信号量
二进制信号量解决了一个完全不同的问题:

  • 等待任务B等待某事发生(例如,传感器跳闸)。
  • 传感器跳闸并运行中断服务程序。 它需要通知行程任务。
  • 任务B应该运行并为传感器跳闸采取适当的措施。 然后回到等待状态。

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

请注意,对于二进制信号量,B可以接收信号量,而A可以给出信号量。
同样,二进制信号量不能保护资源免受访问。 发出信号量和采取信号量的行为从根本上是分离的。
对于相同的二进制信号量来说,相同的任务通常没有什么意义。


#30楼

在Windows中,区别如下。 MUTEX:成功执行等待的过程必须执行一个信号 ,反之亦然。 二进制SEMAPHORES:不同的进程可以对信号量执行等待信号操作。


#31楼

与信号量不同,互斥体具有所有权。 尽管在互斥锁范围内的任何线程都可以获得解锁的互斥锁并锁定对同一关键代码段的访问,但是只有锁定了互斥锁的线程才应对其进行解锁

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二进制信号量和互斥量之间的区别 的相关文章

随机推荐

  • Sqlite连接数据库工具类

    连接数据库 DataBaseConfig span class token annotation punctuation 64 Slf4j span span class token keyword public span span cla
  • Can‘t create directory ‘D:\develop erver\MySQL-8.0.20\data\‘ (OS errno 2 - No such file or director

    错误信息 MySQL8 0安装时遇到的异常 命令 xff1a mysqld initialize console 原因分析 xff1a 提示 xff1a 是因为设置mysql的安装目录和mysql数据库的数据的存放目录是反斜杠的问题 例如
  • Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile

    问题描述 Failed to execute goal org apache maven plugins maven compiler plugin 3 7 0 compile default compile on project xxx
  • 文本比对工具【UltraCompare附安装包】Mac和Windows下载使用

    UltraCompare 强大的文件 xff0c 文件夹 xff0c PDF Word和Excel比较 文件夹同步 xff0c 二进制 十六进制比较 下载一个免费的全功能试用版 xff0c 看看为什么 适用于Windows Mac和Linu
  • 面试问MongoDB和Redis有什么区别?

    MongoDB是一种文档型数据库 xff0c 它以JSON格式存储数据 它适合存储大量的复杂数据 xff0c 例如存储大量结构化数据的应用程序 它提供强大的查询功能和支持分布式部署 Redis则是一种基于内存的数据存储系统 xff0c 它适
  • 在MySQL中查看慢 SQL

    进入 MySQL 命令行工具 可以在终端输入 mysql u 用户名 p xff0c 然后输入密码来登录到 MySQL 输入以下命令开启慢查询日志 xff1a span class token keyword SET span span c
  • 怎么防止SQL注入?

    首先SQL注入是一种常见的安全漏洞 xff0c 黑客可以通过注入恶意代码来攻击数据库和应用程序 以下是一些防止SQL注入的基本措施 xff1a 数据库操作层面 使用参数化查询 xff1a 参数化查询可以防止SQL注入 xff0c 因为参数化
  • WARMING! ! ! BIOS Recovery mode has been detected. Please put the file “ASUS. CAp“ into HDD or a rem

    文章目录 问题场景 xff1a 解决方案 xff1a 步骤1 xff1a 下载适当的BIOS文件步骤2 xff1a 将BIOS文件复制到可移动设备或硬盘驱动器中步骤3 xff1a 进入BIOS恢复模式步骤4 xff1a 恢复BIOS步骤5
  • 如何比较本地git分支与其远程分支?

    如何查看本地分支和远程分支之间的diff xff1f 1楼 第一种 a href http www javaxxz com thread 377026 1 1 html git a branch a 获取可用分支列表 在输出上你可能会看到类
  • VuePress1.x使用及个人博客搭建

    文章目录 介绍快速开始安装目录页面配置 介绍 VuePress 由两部分组成 xff1a 一个以 Vue 驱动的主题系统的简约静态网站生成工具 xff0c 和一个为编写技术文档而优化的默认主题 它是为了支持 Vue 子项目的文档需求而创建的
  • Git项目同时推送到GitHub和Gitee详细操作

    文章目录 前言一 创建仓库 Create a new repository 二 初始化三 配置公钥四 密钥验证五 代码推送 总结 前言 将Git项目同时推送到GitHub和Gitee的好处如下 xff1a 提高代码可见性和协作性 xff1a
  • VMware虚拟机安装CentOS8详细教程

    文章目录 一 下载安装包二 创建虚拟机1 安装 VMware2 创建虚拟机3 编辑虚拟机设置 三 系统安装1 开始安装2 时区设置3 分区设置4 配置网络6 开机密码7 配置安装源8 安装 四 系统配置1 网络检查2 配置静态IP地址 一
  • ChatGPT API调用+服务器部署【附Git地址】

    文章目录 一 关键代码二 使用步骤1 获取代码2 服务器部署 总结 运行对话效果图 一 关键代码 span class token keyword public span span class token keyword class spa
  • zookeeper超详细安装集群部署

    文章目录 一 zookeeper官网下载二 JDK环境安装三 zookeeper安装1 zookeeper解压2 zookeeper配置文件介绍 克隆服务器1 网络检查2 集群配置3 启动集群4 错误记录 一 zookeeper官网下载 下
  • VMware虚拟机克隆、复制虚拟机

    文章目录 为什么要克隆一 环境检查二 开始克隆三 网卡静态配置 为什么要克隆 首先VMware 上创建的虚拟机是可以重复使用的 xff0c 安装好的虚拟机可以直接复制或者剪切到其它任意电脑上 xff0c 然后使用 VMware 打开使用 x
  • CentOS7【管理防火墙端口命令】

    查看防火墙状态 xff1a firewall span class token operator span cmd span class token operator span state 开启防火墙 xff1a systemctl sta
  • Package ‘ufw‘ has no installation candidate问题已解决

    错误提示 xff1a Reading package lists Done Building dependency tree Done Package aptitude is not available but is referred to
  • 用git下载单个分支

    原文发在github io博客 转载写明出处 xff1a http landerlyoung github io blog 2014 01 06 yong gitxia zai dan ge fen zhi 最近在玩octpress 开始一
  • ubuntu18 安装ros-melodic 的踩坑记录

    今天运行a loam程序才发现重装之后的ubuntu18没装ros 于是去查了怎么去查找ros系统的版本 先在终端输入roscore 打开新终端 xff0c 再输入 xff0c rosparam list 再输入rosparam get r
  • 二进制信号量和互斥量之间的区别

    二进制信号量和互斥量之间是否有任何区别 xff0c 或者它们基本相同 xff1f 1楼 它们的同步语义非常不同 xff1a 互斥锁允许序列化对给定资源的访问 xff0c 即多个线程一次等待一个锁 xff0c 并且如前所述 xff0c 该线程