• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

IOS线程池

[复制链接]
菜鸟教程小白 发表于 2022-12-12 11:53:03 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我有这个方法

-(void)addObjectToProcess(NSObject*)object;

并且我希望此方法将对象添加到可以并行处理多达 4 个对象的进程队列中。

我已经创建了自己的 dispatch_queue 和 semhphore

 _concurrentQueue = dispatch_queue_create([queue_id UTF8String],DISPATCH_QUEUE_CONCURRENT);
 _processSema = dispatch_semaphore_create(4);

方法的实现是:

-(void)addObjectToProcess(NSObject*)object {
    dispatch_semaphore_wait(self.processSema, DISPATCH_TIME_FOREVER);
    __weak MyViewController* weakSelf = self;

    dispatch_async(self.concurrentQueue, ^{
        // PROCESS...........
        // ..................
        dispatch_semaphore_signal(self.processSema);
        dispatch_async(dispatch_get_main_queue(), ^{
            // call delegate from UI thread
        });
    });
    }

似乎调用者有时会因为信号量障碍而被阻塞。

还有其他/更简单的选择来实现我在这里尝试做的事情吗?

谢谢



Best Answer-推荐答案


问题是您在调用 addObjectToProcess 的任何线程(可能是主线程)上调用 dispatch_semaphore_wait。因此,如果您已经有四个任务在运行,那么当您安排这第五个进程时,它将在主线程上等待。

不过,您不只是想将等待信号量移动到分派(dispatch)到 self.concurrentQueue 的 block 中,因为这样会成功地将“PROCESS”任务限制为四个时间,您将为这些积压的调度任务中的每一个消耗另一个工作线程,并且这些工作线程的数量是有限的。当你用尽这些时,你可能会对其他进程产生不利影响。

解决此问题的一种方法是在并发处理队列之外创建一个串行调度队列,然后将整个调度任务异步分派(dispatch)到该调度队列。因此,您可以享受进程队列的最大并发性,同时既不会阻塞主线程,也不会用完工作线程来处理积压的任务。例如:

@property (nonatomic, strong) dispatch_queue_t schedulingQueue;

self.schedulingQueue = dispatch_queue_create("com.domain.scheduler", 0);

- (void)addObjectToProcess(NSObject*)object {
    dispatch_async(self.schedulingQueue, ^{
        dispatch_semaphore_wait(self.processSema, DISPATCH_TIME_FOREVER);
        typeof(self) __weak weakSelf = self;

        dispatch_async(self.concurrentQueue, ^{
            // PROCESS...........
            // ..................
            typeof(self) __strong strongSelf = weakSelf;
            if (strongSelf) {
                dispatch_semaphore_signal(strongSelf.processSema);
                dispatch_async(dispatch_get_main_queue(), ^{
                    // call delegate from UI thread
                });
            }
        });
    });
} 

另一个好方法(特别是如果“PROCESS”是同步的)是使用具有 maxConcurrentOperationCountNSOperationQueue,它可以为您控制并发程度。例如:

@property (nonatomic, strong) NSOperationQueue *processQueue;

并初始化它:

self.processQueue = [[NSOperationQueue alloc] init];
self.processQueue.maxConcurrentOperationCount = 4;

然后:

- (void)addObjectToProcess(NSObject*)object {
    [self.processQueue addOperationWithBlock:^{
        // PROCESS...........
        // ..................
        dispatch_async(dispatch_get_main_queue(), ^{
            // call delegate from UI thread
        });
    }];
}

唯一的窍门是“PROCESS”本身是否是异步的。如果你这样做,那么你不能只使用 addOperationWithBlock,而是必须编写自己的自定义异步 NSOperation 子类,然后使用 addOperationNSOperationQueue。编写异步 NSOperation 子类并不难,但有一些与此相关的小细节。见 Configuring Operations for Concurrent Execution并发编程指南中。

关于IOS线程池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38812161/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap