美文网首页
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的核心

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