SDWebImageManager 基于信号量来调度图片下载操作

一、创建信号量 保证关键代码段不被并发调用。

@interface SDWebImageManager ()

@property (strong, nonatomic, readwrite, nonnull) SDImageCache *imageCache;
@property (strong, nonatomic, readwrite, nonnull) id<SDImageLoader> imageLoader;
@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;
@property (strong, nonatomic, nonnull) dispatch_semaphore_t failedURLsLock; // a lock to keep the access to `failedURLs` thread-safe
@property (strong, nonatomic, nonnull) NSMutableSet<SDWebImageCombinedOperation *> *runningOperations;
@property (strong, nonatomic, nonnull) dispatch_semaphore_t runningOperationsLock; // a lock to keep the access to `runningOperations` thread-safe

@end

_runningOperationsLock = dispatch_semaphore_create(1);

如果 value > 0,就相当于创建了个信号量,并同时发出value个信号。
如果 value = 0,就相当于单纯仅仅创建了个信号量,还没发信号。
如果 value < 0,直接failure,返回一个NULL。

二、线程安全操作加锁

- (void)safelyRemoveOperationFromRunning:(nullable SDWebImageCombinedOperation*)operation {
    if (!operation) {
        return;
    }
    SD_LOCK(self.runningOperationsLock);
    [self.runningOperations removeObject:operation];
    SD_UNLOCK(self.runningOperationsLock);
}

#ifndef SD_LOCK
#define SD_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif

#ifndef SD_UNLOCK
#define SD_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif

等待信号量:dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER) 

传入所要等待信号的信号量。dispatch_semaphore_t的信号计数-1。 超时等待时间。超过该时间就返回非0,并会直接往下执行。
也可以设置为DISPATCH_TIME_FOREVER,永久等待。

发送信号量:dispatch_semaphore_signal(lock);

传入所要发送信号的信号量。dispatch_semaphore_t的信号计数+1。

三、信号量的应用

在多线程并发的场景,通过控制信号量来保证操作的同步。

- (void)testFunc{
    
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        NSLog(@"任务1:%@",[NSThread currentThread]);
        
        dispatch_semaphore_signal(sem);
        
    });
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        NSLog(@"任务2:%@",[NSThread currentThread]);
        
        dispatch_semaphore_signal(sem);
    });
    
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        NSLog(@"任务3:%@",[NSThread currentThread]);
        
    });
}

2021-05-12 11:08:27.074869+0800 learnDISsemaphore[1412:64135] 任务1:<NSThread: 0x600002051a40>{number = 6, name = (null)}

2021-05-12 11:08:27.075174+0800 learnDISsemaphore[1412:64135] 任务2:<NSThread: 0x600002051a40>{number = 6, name = (null)}

2021-05-12 11:08:27.075358+0800 learnDISsemaphore[1412:64135] 任务3:<NSThread: 0x600002051a40>{number = 6, name = (null)}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值