GCD封装实现最大并发数

本文介绍了一个基于Grand Central Dispatch (GCD)的Objective-C并发队列类库——GCDPropertyQueue。该库提供了不同优先级的全局队列、后台队列及主线程队列等,并实现了异步和同步调度方法。

//

//  QDispatchQueue.h

//  GCDPropertyQueue

//

//  Created by maochengfang on 2020/10/28.

//

 

#import <Foundation/Foundation.h>

 

NS_ASSUME_NONNULL_BEGIN

 

@interface QDispatchQueue : NSObject

 

+ (QDispatchQueue *)mainThreadQueue;

+ (QDispatchQueue *)defaultGlobalQueue;

+ (QDispatchQueue *)lowGlobalQueue;

+ (QDispatchQueue *)hightGlobalQueue;

+ (QDispatchQueue *)backGroundGlobalQueue;

 

 

@property (nonatomic, assign, readonly) NSUInteger concurrentCount;

 

- (instancetype)init;

 

- (instancetype)initWithQueue:(dispatch_queue_t)queue;

 

- (instancetype)initWithQueue:(dispatch_queue_t)queue concurrentCount:(NSUInteger)concurrentCount;

 

- (void)sync:(dispatch_block_t)block;

 

- (void)async:(dispatch_block_t)block;

 

@end

 

NS_ASSUME_NONNULL_END

 

//

//  QDispatchQueue.m

//  GCDPropertyQueue

//

//  Created by maochengfang on 2020/10/28.

//

 

#import "QDispatchQueue.h"

 

static const NSUInteger kDefaultConcurrentCount = 1; //默认/最小并发数

static const NSUInteger kGlobalConcurrentCount = 4; //默认全局队列线程并发数

static const NSUInteger kMaxConcurrentCount = 32;    //最大并发数

 

@interface QDispatchQueue ()

 

@property (nonatomic, strong) dispatch_queue_t serialQueue;

@property (nonatomic, strong) dispatch_semaphore_t semaphore;

@property (nonatomic, strong) dispatch_queue_t queue;

@property (nonatomic, assign) NSUInteger concurrentCount;

 

@end

 

@implementation QDispatchQueue

 

+ (QDispatchQueue *)mainThreadQueue{

    static QDispatchQueue *queue;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        

        queue = [[QDispatchQueue alloc] initWithQueue:dispatch_get_main_queue()];

    });

    return queue;

}

 

+ (QDispatchQueue *)lowGlobalQueue{

    static QDispatchQueue  *queue;

    static dispatch_once_t onceToken;

    

    dispatch_once(&onceToken, ^{

        queue = [[QDispatchQueue alloc] initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0) concurrentCount:(NSUInteger)kDefaultConcurrentCount];

    });

    return  queue;

}

 

+ (QDispatchQueue *)hightGlobalQueue{

    static QDispatchQueue *queue;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        queue = [[QDispatchQueue alloc] initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) concurrentCount:(NSUInteger)kDefaultConcurrentCount];

    });

    return  queue;

}

 

+ (QDispatchQueue *)backGroundGlobalQueue{

    static QDispatchQueue * queue;

    static dispatch_once_t onceToken;

    

    dispatch_once(&onceToken, ^{

        queue = [[QDispatchQueue alloc] initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) concurrentCount:(NSUInteger)kDefaultConcurrentCount];

    });

    

    return  queue;

}

 

 

 

- (instancetype)init{

    return  [self initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) concurrentCount:(NSUInteger)kDefaultConcurrentCount];

}

 

- (instancetype)initWithQueue:(dispatch_queue_t)queue{

    return [self initWithQueue:queue concurrentCount:kDefaultConcurrentCount];

}

 

- (instancetype)initWithQueue:(dispatch_queue_t)queue concurrentCount:(NSUInteger)concurrentCount{

    

    self = [super init];

    

    if(self){

        if(!queue){

            _queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

            

        }else{

            _queue = queue;

            

            _concurrentCount = concurrentCount;

            

            if(concurrentCount < kDefaultConcurrentCount){

                concurrentCount = kDefaultConcurrentCount;

            }

            

            _concurrentCount = concurrentCount;

            

            if(!_semaphore){

                _semaphore = dispatch_semaphore_create(concurrentCount);

            }

            

            if(!_serialQueue){

                _serialQueue = dispatch_queue_create([[NSString stringWithFormat:@"com.maozeze.nanhua.serial_%p",self] UTF8String], DISPATCH_QUEUE_SERIAL);

            }

        }

    }

    

    return  self;

}

 

 

 

- (void)sync:(dispatch_block_t)block{

    

    if(!block){

        return;

    }

    

    dispatch_sync(_serialQueue, ^{

       

        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);  //semaphore -1

        dispatch_sync(self.queue, ^{

            if(block){

                block();

            }

            dispatch_semaphore_signal(self.semaphore); //semaphore +1

        });

    });

    

}

 

- (void)async:(dispatch_block_t)block{

    if(!block){

        return;

    }

    

    dispatch_async(self.serialQueue, ^{

       

        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER); //semaphore -1

        dispatch_async(self.queue, ^{

            if(block){

                block();

            }

            dispatch_semaphore_signal(self.semaphore); //semaphore +1

        });

    });

}

 

@end

测试异步和同步

- (void)testAsync{

    dispatch_queue_t workConcurrentQueue = dispatch_queue_create("com.jzp.async.queue", DISPATCH_QUEUE_CONCURRENT);

    QDispatchQueue *queue = [[QDispatchQueue alloc]initWithQueue:workConcurrentQueue concurrentCount:3];

    for (NSInteger i = 0; i < 10; i++) {

        [queue async:^{

            NSLog(@"thread-info:%@开始执行任务%d",[NSThread currentThread],(int)i);

            sleep(1);

            NSLog(@"thread-info:%@结束执行任务%d",[NSThread currentThread],(int)i);

        }];

    }

    NSLog(@"异步:主线程任务...");

}

 

- (void)testSync{

    dispatch_queue_t workConcurrentQueue = dispatch_queue_create("com.jzp.sync.queue", DISPATCH_QUEUE_CONCURRENT);

    QDispatchQueue *queue = [[QDispatchQueue alloc]initWithQueue:workConcurrentQueue concurrentCount:1];

    for (NSInteger i = 0; i < 10; i++) {

        [queue sync:^{

            NSLog(@"thread-info:%@开始执行任务%d",[NSThread currentThread],(int)i);

            sleep(1);

            NSLog(@"thread-info:%@结束执行任务%d",[NSThread currentThread],(int)i);

        }];

    }

    NSLog(@"异步:主线程任务...");

}

### C++ STL Queue Usage and Examples In C++, `std::queue` is part of the Standard Template Library (STL), which provides a convenient way to implement queues using templates. A queue follows the First-In-First-Out (FIFO) principle where elements are inserted from one end called rear and deleted from another end known as front. To use `std::queue`, include `<queue>` header file. Here’s how one can define and initialize a queue: ```cpp #include <iostream> #include <queue> int main() { std::queue<int> q; } ``` Adding elements into the queue uses member function `push()` or `emplace()`. Removing elements employs `pop()`. Accessing but not removing the first element utilizes `front()`, while checking whether the queue is empty relies on `empty()`. To get the number of elements currently stored within the container adaptor, apply `size()` method[^1]. Below demonstrates basic operations with integers in a queue: ```cpp #include <iostream> #include <queue> void showQueue(std::queue<int> gq){ while (!gq.empty()){ std::cout << '\t' << gq.front(); gq.pop(); } } int main(){ std::queue<int> gquiz; gquiz.push(10); gquiz.push(20); std::cout << "The queue gquiz is : "; showQueue(gquiz); std::cout<<"\ngquiz.size() : "<<gquiz.size(); return 0; } ``` For more complex data structures like strings or custom objects, similar methods apply without modification needed since these functions work generically over different types through template instantiation mechanisms provided by C++. However, when dealing specifically with boolean values inside vectors (`std::vector<bool>`), special attention should be paid due to its unique implementation involving proxies rather than direct storage of bools [^2]. This does not affect standard queues directly unless such specialized containers become involved indirectly via contained elements.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值