转载 同步和互斥 线程同步和互斥的区别

原文地址:同步和互斥作者:andrew

windows 下线程的同步和互斥的方法

1。互斥量 Mutex

2。事件 event

3. 信号量 Semaphore

4. 临界区 Critical section

互斥与同步

互斥和同步是两个紧密相关而又容易混淆的概念。

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源,如“第一类读写者模型”。

Windows下的互斥同步机制

Windows下提供了多种内核对象实现线程、进程间的同步和互斥,常用的有:

关键节(Critical Section):关键节不是内核对象,在用户态实现了同一进程中线程的互斥。由于使用时不需要从用户态切换到核心态,所以速度很快(X86系统上约为20个指令周期),但其缺点是不能跨进程同步,同时不能指定阻塞时的等待时间,只能无限等待。

互斥体:(Mutex):互斥体实现了和关键节类似的互斥功能,但区别在于:互斥体是内核对象,可以实现跨进程互斥,但需要在用户态和核心态之间切换,速度比关键节慢得多(X86系统上约为600个指令周期),同时可以指定阻塞时的等待时间。

事件(Event):事件也是内核对象,具有“信号态”和“无信号态”两种状态。当某一线程等待一个事件时,如果事件为信号态,将继续执行,如果事件为无信号态,那么线程被阻塞。线程能够指定阻塞时的等待时间。

信号量(Semaphore):信号量是一个资源计数器,当某线程获取某信号量时,信号量计数首先减1,如果计数小于0,那么该线程被阻塞;当某县城释放某信号量时,信号量计数首先加1,如果计数小于或等与0,那么唤醒某被阻塞的线程并执行之。对信号量的总结如下:

1.如果计数器m大于0,表示还有m个资源可以访问,此时信号量线程等待队列中没有线程被阻塞,新的线程访问资源也不会被阻塞;

2.如果计数器m等与0,表示没有资源可以访问,此时信号量线程等待队列中没有线程被阻塞,但新的线程访问资源会被阻塞;

3.如果计数器m小于0,表示没有资源可以访问,此时信号量线程等待队列中有abs(m)个线程被阻塞,新的线程访问资源会被阻塞;

信号量常被用于保证对多个资源进行同步访问。

生产者-消费者模型

生产者-消费者模型是指:

1. 生产者进行生产将物品放入仓库,同一时间只能有一个生产者将物品放入仓库,如果仓库满,生产者等待。

2. 消费者从仓库中取出物品,同一时间只能有一个消费者取出物品,如果仓库空,消费者等待;

3. 生产者将物品放入仓库时消费者不能同时取;

4. 消费者取物品时生产者不能放入物品;

总之,就是生产者群体或消费者群体内部是互斥的,两个群体之间是同步的。

当只有一个生产者、消费者时,由于同一群体内部不需要互斥,所以只需在群体之间实现同步即可。例如可以使用两个Event/CriticalSection/Mutex/Semaphore实现同步;

如果有多个生产者和消费者,那么情况会复杂些,需要一个Event/CriticalSection/Mutex实现线程之间的互斥,需要两个Semaphore实现两个线程群体间的同步。一个例子如下:

HANDLE m_S_Producer; // Semaphore

HANDLE m_S_Consumer; // Semaphore

HANDLEm_E_Queue; //Event

// 假设仓库最多容纳M个物品,开始仓库为空

m_S_Producer = CreateSemaphore(NULL, M, M, NULL); //初始计数为M

m_S_Consumer = CreateSemaphore(NULL, 0, M, NULL); //初始计数为0

m_E_Queue = CreateEvent(NULL, FALSE, TRUE, NULL);//自动类型,初始状态为信号态

生产者

if (WaitForSingleObject(m_S_Producer, WaitTime) ==WAIT_OBJECT_0)

{

if (WaitForSingleObject(m_E_Queue, WaitTime) == WAIT_OBJECT_0)

{

// OK now, put product

// relase comsumer’s semaphore

ReleaseSemaphore(m_S_Consumer, 1, NULL);

// set event to signal

SetEvent(m_E_Queue);

return TRUE;

}

else // wait event time out

{

// not put product so release producer

ReleaseSemaphore(m_S_Producer, 1, NULL);

SetEvent(m_E_Queue);

return FALSE;

}

}

else // wait semaphore time out

{

return FALSE;

}

消费者

if (WaitForSingleObject(m_S_Consumer, WaitTime) ==WAIT_OBJECT_0)

{

if (WaitForSingleObject(m_E_Queue, WaitTime) == WAIT_OBJECT_0)

{

// OK now, Get product then

// releasee productor’s semaphore

ReleaseSemaphore(m_S_Producer, 1, NULL);

// set event to signal

SetEvent(m_E_Queue);

return TRUE;

}

else // wait event time out

{

// not get product so release Consumer

ReleaseSemaphore(m_S_Consumer, 1, NULL);

SetEvent(m_E_Queue);

return FALSE;

}

}

else // wait semaphore time out

{

return FALSE;

}

特别需要注意的是,在该模型中,对互斥量(本例为m_E_Queue)的等待必须放在第二个等待位置,否则可能将造成线程死锁。考虑这样的情况:仓库已满,没有任何线程访问。某一时刻,生产者放入物品,首先等待m_E_Queue并通过,且将m_E_Queue置于无信号态,然后等待m_S_Produce时被阻塞。这时某一消费者欲取物品,无论在什么情况下,都将在等待m_E_Queue时被阻塞,从而相互等待造成死锁。在释放同步对象时则位置不受限制。

多个生产者一个消费者

这时一种常用的变形。如果仓库是一个队列(先进先出)此时消费者内部将不需要互斥。

消费者

if (WaitForSingleObject(m_S_Consumer, WaitTime) ==WAIT_OBJECT_0)

{

// OK now, Get product then

// releasee productor’s semaphore

ReleaseSemaphore(m_S_Producer, 1, NULL);

return TRUE;

}

else // wait semaphore time out

{

return FALSE;

}

[转载]同步和互斥 线程同步和互斥的区别

此时可能出现消费者、生产者同时访问资源的情况,但生产者群体和消费者群体之间的同步机制,以及队列的先进先出机制将保证即使消费者、生产者同时访问资源,也不会发生冲突。

多个消费者一个生产者的情况类似。

  

爱华网本文地址 » http://www.413yy.cn/a/25101012/124513.html

更多阅读

批量授权、零售版和OEM的区别 oem授权书

批量授权、零售版和OEM的区别——简介批量授权、零售版和OEM的区别当涉及到购买许可证(license)的问题,相信许多人都有过迷茫。不知道一些相应的license的问题。而购买license的渠道很多,那么我们应该要购买哪些license呢?他们的区别又

告诉您高丽参和西洋参的区别方法 高丽参 西洋参 人参

许多消费者都在问高丽参和西洋参的区别。西洋参又称广东人参、花旗参。高丽参和西洋参的区别主要是品种和药用功效的不同,但这两种参都统属人参科。高丽参和西洋参的区别方法高丽参,又叫做韩国红参,是属于热性的中药,大补气血的上品

哈士奇和阿拉斯加的区别 狗狗智商排名

哈士奇和阿拉斯加的区别——简介有一种狗狗和哈士奇长得很像,毛要比哈士奇长了许多。不要惊讶,它叫“阿拉斯加”。原产美国的阿拉斯加州,为什么它长得那么像哈士奇,而且都是雪橇犬呢?接下来,就让我们一起揭开它们神秘的面纱!哈士奇和阿拉

文旦和柚子的区别 姑娘果的功效与作用

文旦和柚子的区别——简介文旦和柚子是属于关系,文旦是柚子的一种文旦和柚子的区别——工具/原料文旦和柚子是属于关系,文旦是柚子的一种文旦和柚子的区别——方法/步骤文旦和柚子的区别 1、文旦 名称:文旦 产地:浙江台州玉环 别名

声明:《转载 同步和互斥 线程同步和互斥的区别》为网友我叫逞强分享!如侵犯到您的合法权益请联系我们删除