面试宝点

控制GCD并发线程数

2018-08-28  本文已影响17人  upworld

Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并发任务,可在 iOS 4 及以上版本使用。

GCD 会自动利用更多的 CPU 内核(比如双核、四核)。但是有时候创建的并行queue太多,有可能造成开辟线程过多。下面会封装一个ThreadManager,底层也会调用GCD,但是会控制同时并发线程的数量。实现原理非常简单。ThreadManager 有一个asynBlock方法,asynBlock 方法会把一些block 异步到一个常驻线程。异步常驻线程会有一个数组维护Block,dispatch_semaphore_t 来控制线程的并发数。

@interface ThreadManager ()

@property (atomic, strong) NSLock *lock;
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@property (nonatomic, strong) NSMutableArray *blocks;
@property (nonatomic, strong) NSThread *thread;

@end

@implementation ThreadManager

+ (instancetype)shareInstance{
    static dispatch_once_t onceToken;
    static ThreadManager *manager = nil;
    dispatch_once(&onceToken, ^{
        manager = [ThreadManager new];
    });
    return manager;
}

- (instancetype)init{
    if (self = [super init]) {
        //5 not 6
        _semaphore = dispatch_semaphore_create(5);
        _lock = [[NSLock alloc] init];
        _blocks = [NSMutableArray array];
        _thread = [[NSThread alloc] initWithTarget:self selector:@selector(testRun) object:nil];
        [_thread start];
    }
    return  self;
}

- (void)testRun{
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
}

- (void)asynBlock:(dispatch_block_t)block{
    NSLog(@"asynBlock begin");
    [self.lock lock];
    [_blocks addObject:block];
    [self.lock unlock];
    
    [self performSelector:@selector(excuteBlock) onThread:self.thread withObject:nil waitUntilDone:NO];

    NSLog(@"asynBlock block end");
    

}


- (void)excuteBlock{
    [self.lock lock];
    if (_blocks.count > 0) {
        dispatch_block_t block = [_blocks firstObject];
        [_blocks removeObjectAtIndex:0];
        [self doBlock:block];
    }
    [self.lock unlock];
}

- (void)doBlock:(dispatch_block_t)block{
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
//    [NSThread detachNewThreadWithBlock:^{
//        block();
//        dispatch_semaphore_signal(self.semaphore);
//    }];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        block();
        dispatch_semaphore_signal(self.semaphore);
    });
}

@end
上一篇下一篇

猜你喜欢

热点阅读