我的 博客地址
說起生產(chǎn)者消費(fèi)者問題(Producer-consumer problem),相信大家都印象深刻,有遺忘可以看看wiki上的解釋,我們今天來聊聊怎么用 GCD 實(shí)現(xiàn)一個(gè)生產(chǎn)者消費(fèi)者模型。
我們先理一下思路,看看問題關(guān)鍵點(diǎn):
- 生產(chǎn)者生成產(chǎn)品放到緩沖區(qū)中,然后重復(fù)此過程,但是生產(chǎn)的產(chǎn)品數(shù)量不能超過緩沖區(qū)大小,如果緩沖區(qū)滿了,停止生產(chǎn)新的產(chǎn)品,等待緩沖區(qū)有空位;
- 消費(fèi)者不停從緩沖區(qū)取出產(chǎn)品,如果緩沖區(qū)空了,則停止消費(fèi),等待新的產(chǎn)品放到緩沖區(qū)中;
很容易就聯(lián)想到信號(hào)量 dispatch_semaphore_t ,我們需要使用兩個(gè)信號(hào)量分別控制生產(chǎn)者與消費(fèi)者,semaphoreProduce 控制生產(chǎn)者當(dāng)緩沖區(qū)滿時(shí)停止生產(chǎn),semaphoreConsume 控制消費(fèi)者當(dāng)緩沖區(qū)空時(shí)停止消費(fèi)。如下圖所示(配圖純手工制作,輕噴??):

靈魂畫手配圖??
Show me the code.
// 控制生產(chǎn)者的信號(hào)量
dispatch_semaphore_t semaphoreProduce;
// 控制消費(fèi)者的信號(hào)量
dispatch_semaphore_t semaphoreConsume;
// 當(dāng)前產(chǎn)品數(shù)量
int productCount = 0;
// 緩沖區(qū)大小
const int bufferSize = 5;
// 初始化生產(chǎn)者、消費(fèi)者信號(hào)量
- (void)initProducerAndConsume {
// 初始化緩沖區(qū)大小
semaphoreProduce = dispatch_semaphore_create(bufferSize);
semaphoreConsume = dispatch_semaphore_create(0);
}
// 生產(chǎn)商品
- (void)produce {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_wait(semaphoreProduce, DISPATCH_TIME_FOREVER);
[NSThread sleepForTimeInterval:1];
productCount++;
NSLog(@"生產(chǎn)商品,商品總量:%d", productCount);
dispatch_semaphore_signal(semaphoreConsume);
});
}
// 消費(fèi)商品
- (void)consume {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_wait(semaphoreConsume, DISPATCH_TIME_FOREVER);
[NSThread sleepForTimeInterval:1];
productCount--;
NSLog(@"消費(fèi)商品,商品總量:%d", productCount);
dispatch_semaphore_signal(semaphoreProduce);
});
}