多线程编程指南

Threading Programming Guide的中文翻译版本,由于个人精力有限,很多地方必然会出现错误,希望我们共同修改,另一个目的也是作为个人笔记之用。如要转载请注明出处

  1. 微博:凌云壮志幾多愁
  2. 博客:凌云壮志幾多愁
  3. 简书:凌云壮志几多愁

文章梳理

个人最后面进行一个梳理,肯定会有理解不到的地方,如果不想看可直接跳过。

一、线程创建

  1. 线程技术包括NSThread,posix等等。具体创建见“线程管理”一节。
  2. 如果不使用Runloop的话,线程在完成了入口点函数之后当前线程就会退出,为了保持线程常驻,我们需要Runloop。

二、Runloop

  1. 苹果不允许直接创建Runloop,每个线程在创建时系统会为他创建一个Runloop,用[NSRunLoop currentRunLoop]获取,或者在CoreFoundation中使用CFRunLoopGetCurrent();
  2. 同样为了能够让Runloop能够一直循环下去(如果要Runloop退出可以设定超时时间),我们必须要为其添加输入源(事件源)抑或定时器源或者Observer,而这些源必须要添加到Mode中。
  3. 如果在Runloop中,我们不想去添加定时器源,或者输入源。最简单的办法就是在Runloop中添加一个Port:
NSPort *port = [NSMachPort port];
if (!port) {
    return;
}
[port setDelegate:self];
[[NSRunLoop currentRunLoop] addPort:port forMode:NSDefaultRunLoopMode];
[NSThread detachNewThreadSelector:@selector(detachThread:) toTarget:self withObject:nil];

上诉知识具体见"Runloop"一节。

三、同步工具

在多线程程序中如果发生了对特定资源的竞争,这时就需要使用同步工具。由于使用同步工具会造成性能消耗,建议如下:

并发任务的最好的实现办法就是减少交互和相互依赖。如果每一个任务都是在它私有的数据集上做操作,这种情况就不需要使用锁来保护数据。就算是两个任务同时使用同一份数据集,我们可以让该数据集进行分区使用,或者为每一个任务复制一份数据。当然,复制数据也是有消耗的,所以就得衡量一下谁的消耗更高。

  1. 如果多个线程同时去获取特定资源,而且该资源被加锁,那么必须要先获取锁然后才能获取相应的资源。
  2. 同时在获取锁时,如果是互斥锁的话,必须要等到前一个线程释放该锁之后,另一个线程才能去获取该锁,获取了该锁然后获取资源。

上诉知识具体见"同步"一节。

四、总结

来总结一波:

因为在主线程执行耗时操作会影响用户体验 -----> 所以我们得需要使用多线程技术(子线程)-----> 由于子线程在执行一次之后就会退出,所以我们的使用Runloop(Runloop的保活又需要使用Mode) -----> 由于多线程在资源争夺方面的问题 -----> 我们得使用锁 -----> 由于使用多个锁的时候会造成死锁或者活动锁 -----> 所以我们在同一时刻最好的办法就是只用一个锁。

五、配套DEMO

[Github]Thread_Programming;

results matching ""

    No results matching ""