美文网首页
RunLoop的核心

RunLoop的核心

作者: 幸运的小强本人 | 来源:发表于2016-06-21 13:37 被阅读94次

RunLoop的核心部分就是当有任务需要处理的时候,线程被唤醒,执行指定的任务。当没有任务需要处理的时候,线程处于休眠状态。直到有新的任务将其唤醒为止。

这里就牵涉到两个线程之间的通信问题。在iOS 中,RunLoop 使用的是mach port的通信方式。当线程没有任务需要处理的时候,它就调用mach_msg 函数,使线程处于休眠状态,同时在指定端口等待被唤醒。当另外一个线程完成了自己的任务,需要唤醒前面的线程,处理一定的操作的时候,也是调用mach_msg 函数,向线程等待消息的端口发送消息。然后,系统就会将休眠的线程唤醒,就可以执行相关的操作了。

就是这样,RunLoop实现了线程有任务的时候,处理任务,没有任务的时候处于休眠状态,不消耗任何CPU资源。避免了忙等等情况的出现。

下面简单列出两个线程之间通信的代码:

@implementation ViewController {
    mach_port_t mPort;
}

- (void)viewDidLoad {
  [super viewDidLoad];

   NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
   [thread start];


  UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
  btn.backgroundColor = [UIColor redColor];
  btn.frame = CGRectMake(100, 100, 100, 50);
  [btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:btn];
}  

- (void)btnClicked {
  kern_return_t result;
  mach_msg_header_t header;
  header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
  header.msgh_size = sizeof(mach_msg_header_t);
  header.msgh_remote_port = mPort;
  header.msgh_local_port = MACH_PORT_NULL;
  header.msgh_id = 0;
  result = mach_msg(&header, MACH_SEND_MSG, header.msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);

  if (result == MACH_SEND_TIMED_OUT) mach_msg_destroy(&header);
}

- (void)test {
    mach_port_t result = 0;
    kern_return_t ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &result);

    ret = mach_port_insert_right(mach_task_self(), result, result, MACH_MSG_TYPE_MAKE_SEND);

    mach_port_limits_t limits;
    limits.mpl_qlimit = 2;
    ret = mach_port_set_attributes(mach_task_self(), result, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, MACH_PORT_LIMITS_INFO_COUNT);

    if (KERN_SUCCESS != ret) {
        char msg[256];
        snprintf(msg, 256, "*** The system has no mach ports available. You may be able to diagnose which application(s) are using ports by using 'top' or Activity Monitor. (%d) ***", ret);
     }
    mPort = result;
    uint8_t msg_buffer[3 * 1024];
    mach_msg_header_t *msg = NULL;
    msg = (mach_msg_header_t *)msg_buffer;
    msg->msgh_id = 0;
    msg->msgh_bits = 0;
    msg->msgh_remote_port = MACH_PORT_NULL;
    msg->msgh_size = sizeof(mach_msg_header_t);
    msg->msgh_local_port = result;

    NSLog(@"start");
    int ret1 = mach_msg(msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, msg->msgh_size, result, 1000000, MACH_PORT_NULL);
    if (ret1 == MACH_MSG_SUCCESS) {
        NSLog(@"hahahahahh");
    }
    NSLog(@"********");
}

相关文章

  • RunLoop 源码阅读

    获取runloop的函数 创建runloop的函数 运行runloop的函数 Runloop 运行的核心函数__C...

  • RunLoop介绍

    RunLoop 的概念 RunLoop 与线程的关系 RunLoop核心数据结构 CFRunLoopRef CFR...

  • RunLoop和线程关系

    1.runloop与线程是一一对应的,一个runloop对应一个核心的线程,为什么说是核心的,是因为runloop...

  • RunLoop的核心

    RunLoop的核心部分就是当有任务需要处理的时候,线程被唤醒,执行指定的任务。当没有任务需要处理的时候,线程处于...

  • RunLoop 原理和核心机制(摘自网络)

    RunLoop 原理和核心机制

  • runloop 小结

    OC的两大核心runtime和runloop runloop简介 runloop本质上是一个do-while循环,...

  • AsyncDisplayKit使用的技术原理之一——Runloo

    Runloop work distribution (Runloop任务分发)是ASDK使用的比较核心的一种技术...

  • Runloop

    1、Runloop 和 线程 的关系 1、runloop与线程是一一对应的,一个runloop对应一个核心的线程,...

  • runloop 核心点

    概述 主要参考一些面试中提问的点,来从核心角度理解runloop 想要全面理解,可以参考经典文章:深入理解Runl...

  • iOS复习之RunLoop

    1、事件循环2、用户态3、核心态4、常驻线程 主要 RunLoop文章:RunLoop入门 看我就够了iOS - ...

网友评论

      本文标题:RunLoop的核心

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