春暖花开~~

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

对于线程来说,信号量跟互斥锁是非常重要的概念,可以避免死锁或者读脏数据,然而两者区别也需要我们注意。

对于互斥锁(Mutex)来说,只要有线程占有了该资源,那么不好意思,其他线程就是优先级再高,您也得等着,等我用完再说。我用完之后资源你们爱怎么抢都行,我占有资源的时候别人都不许抢,申请该资源的线程一律等待。

信号量(Semaphore)就更灵活一点,我们如果想把我用完的资源给我关系好的人,就申请一个信号量,这个信号量只有我们几个知道,我用完资源就偷偷通知关系好的这几个,这几个哥们再有序申请资源,别的人干瞪眼。

下面严肃解释一下:

互斥锁(Mutex)保证了使用资源线程的唯一性和排他性,但是无法限制资源释放后其他线程申请的顺序问题,所以是无序的。

而信号量(Semaphore)一般就是互斥的(少许情况读取是可以同时申请的),其保证了线程执行的有序性,可以理解为从一到多的进步,像比较有名的理发厅问题,我们就需要设一个Integer而非Boolean,因为理发厅里面的座椅不可能只有一张。

互斥锁必须由单个线程获取和释放。

信号量是由单个线程释放,另一个线程获取,保证线程同步。

信号量是互斥的进步,Semaphore=1时可以看成互斥锁。

================

  我模拟一个最典型的使用semaphore的场景:a源自一个线程,b源自另一个线程,计算c = a + b也是一个线程。(即一共三个线程)显然,第三个线程必须等第一、二个线程执行完毕它才能执行。在这个时候,我们就需要调度线程了:让第一、二个线程执行完毕后,再执行第三个线程。此时,就需要用semaphore了。

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

// semaphore的机制我在这里就不讲了,百度一下你就知道。
// semaphore_increase对应sem_post
// semaphore_decrease对应sem_wait

简而言之,锁是服务于共享资源的;而semaphore是服务于多个线程间的执行的逻辑顺序的。

作者:萝卜干遇上莲藕 链接:https://www.jianshu.com/p/c6ba8bcc22bc 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
posted on 2019-04-16 08:14  聆听花开的声音  阅读(764)  评论(0编辑  收藏  举报