美文网首页
关于线程池常驻线程的实现的思考

关于线程池常驻线程的实现的思考

作者: 林大鹏 | 来源:发表于2021-11-01 21:57 被阅读0次

常驻线程Demo

今天跟朋友讨论一个问题,就是如何实现一个线程的常驻,作为一个iOS开发者,一开始想到的当然是通过runloop来对线程保活,保证线程的常驻;但是除此之外还有其他的方式吗?如果其他的语言没有runloop特性,那它们是如何来保证线程的常驻的,比如说GCD线程池里面的核心线程,是怎样做到常驻的,它应该是C语言实现的,是没有runloop这里的特性的。

我想了下,线程池里面的核心线程的处理逻辑,应该跟runloop的跑圈逻辑是一致的。核心线程执行的是一个死循环的处理逻辑,在这个逻辑里面有任务就处理,没有任务就进入休眠状态,等到新任务到来,再次唤醒,执行任务。

因为这里存在休眠和唤醒状态,所以应该有一个信号量信号量初始化为0,当有新任务到来时,信号量1,然后将任务放到队列里面,这时候线程被唤醒,将信号量1,然后从任务队列里面取出任务,开始执行任务。

按照这个思路实现了下常驻线程,代码如下:

#import "FJFPermanentThread.h"

@implementation FJFPermanentThread {
    NSMutableArray *_actionMarray;
    NSThread *_thread;
    dispatch_semaphore_t _semaphore;
    dispatch_semaphore_t _arraySemaphore;
    bool _cancel;
}


#pragma mark - Life Circle
- (instancetype)init {
    if (self = [super init]) {
        _actionMarray = [NSMutableArray array];
        
        // 创建 信号量
        _semaphore = dispatch_semaphore_create(0);
        // 保证 数组 操作 原子性
        _arraySemaphore = dispatch_semaphore_create(1);
        
        // 创建 线程
        _thread = [[NSThread alloc] initWithTarget:self selector:@selector(handleMessage) object:nil];
        [_thread start];
    }
    return self;
}

#pragma mark - Public Methods
-(void)doAction:(dispatch_block_t)action {
    if (!_cancel) {
        // 将任务 放入数组
        [self actionMarryAddObject:[action copy]];
        // 信号量 加1
        dispatch_semaphore_signal(_semaphore);
    }
}

- (void)cancel {
    _cancel = YES;
    // 线程 取消后,清空所有回调
    [self actionMarryRemoveAllObject];
    // 相当于 发送一个 任务终止 信号
    dispatch_semaphore_signal(_semaphore);
}

#pragma mark - Private Methods
// 处理 消息
- (void)handleMessage {
    while (true) {
        // 等待信号量,信号量减1
        dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
        
        // 收到信号
        if (_cancel) {
            break;
        }
        
        // 开始执行任务
        dispatch_block_t block = [self actionMarryFirstObject];
        if (block) {
            block();
            [self actionMarryRemoveObject:block];
        }
        
    }
}

- (void)actionMarryAddObject:(id)object {
    dispatch_semaphore_wait(_arraySemaphore, DISPATCH_TIME_FOREVER);
    [_actionMarray addObject:object];
    dispatch_semaphore_signal(_arraySemaphore);
}

- (void)actionMarryRemoveObject:(id)object {
    dispatch_semaphore_wait(_arraySemaphore, DISPATCH_TIME_FOREVER);
    [_actionMarray removeObject:object];
    dispatch_semaphore_signal(_arraySemaphore);
}

- (void)actionMarryRemoveAllObject {
    dispatch_semaphore_wait(_arraySemaphore, DISPATCH_TIME_FOREVER);
    [_actionMarray removeAllObjects];
    dispatch_semaphore_signal(_arraySemaphore);
}

- (dispatch_block_t)actionMarryFirstObject {
    dispatch_semaphore_wait(_arraySemaphore, DISPATCH_TIME_FOREVER);
    dispatch_block_t block = [_actionMarray firstObject];
    dispatch_semaphore_signal(_arraySemaphore);
    return block;
}
@end

相关文章

  • 关于线程池常驻线程的实现的思考

    常驻线程Demo[https://github.com/fangjinfeng/MySampleCode] 今天跟...

  • java线程池源码解析

    主要介绍线程池相关知识,关于线程池,首先我们思考下为什么要用线程池。如果单纯的使用线程,线程的创建和销毁都是自己来...

  • 3分钟了解 java线程池ThreadPoolExecutor的

    常用的3个线程池 线程池的7个参数详解 1.corePoolSize:线程池中的常驻核心线程数2.maximumP...

  • juc和多线程并发相关面试题

    线程池7大参数介绍 corePoolSize:线程池中的常驻核心线程数在创建了线程池后,当有请求任务来之后,就会安...

  • 线程以及java线程池实现分享

    线程以及java线程池实现分享 线程简介 JDK线程池的工作原理 JDK线程池的实现细节 1.线程简介-由来 1....

  • JAVA并发梳理(五)线程池

    关于线程池的实现,各自的特点等稍后再补充。现在先总结下如何合理地设置线程池的大小。 线程池中线程的数目是跟线程池所...

  • iOS 多线程面试题(NSThread+runloop实现常驻线

    NSThread+runloop实现常驻线程 NSThread在实际开发中比较常用到的场景就是去实现常驻线程。 由...

  • 线程通讯详解

    关于子线程能否更新UI的思考线程通讯详解线程池-多线程的高效使用姿势 上文我们说到了关于子线程中能否更新UI的问题...

  • Runloop与多线程

    线程是和runloop一一对应的。自己创建的线程默认是没有runloop的。 思考 怎样实现一个常驻线程? 代码实...

  • java多线程面试题

    实现多线程的方法 1.实现Thread接口 2.实现Runnable接口创建线程 3.实现 线程池 创建线程池的代...

网友评论

      本文标题:关于线程池常驻线程的实现的思考

      本文链接:https://www.haomeiwen.com/subject/zmamaltx.html