多线程(IOS)学习笔记

1、除了锁,系统还提供了条件,确保在你的应用程序任务执行的适当顺序。一个条 件作为一个看门人,阻塞给定的线程,直到它代表的条件变为真。当发生这种情况的 时候,条件释放该线程并允许它继续执行

 (如果你使用操作对象,你可以配置你的操作对象之间的依赖关系的顺序确 定任务的执行顺序,这和条件提供的行为非常相似)。

  2、 可以通过使用  applicationShouldTerminate:  的委托方法来延迟程序的中断直到一段时间后或者完成取消。当延迟中断的时候,你 的程序需要等待直到任何周期线程(可连接线程)已经完成它们的任务且调用了  replyToApplicationShouldTerminate:方法。关于更多这些方法的信息,请查阅 NSApplication Class Reference。

3、The minimum allowed stack size for secondary threads is 16 KB and the stack size must be a multiple of 4 KB
512 KB(secondary threads) 8 MB (Mac OS X main thread) 1 MB (iOS main  thread)


 4、对于多线程的应用程序,Cocoa 框架使用锁和其他同步方式来保证代码的正确执 行。为了防止这些锁造成在单线程里面性能的损失,Cocoa 直到应用程序使用  NSThread  类生成它的第一个新的线程的时候才创建这些锁。
因此当你仅使用  POSIX  例程来生成新的线程,Cocoa 不会收到关于你的应用程序当前变为多线程的通知, 为了让  Cocoa  知道你正打算使用多线程,你所需要做的是使用  NSThread  类生成 一个线程,并让它立即退出, 只需要使用  NSThread  来生成一个线程就足够保证  Cocoa  框架所需的锁到位。
可以使用  NSThread    isMultiThreaded  方法来检验一下。

5、 每个线程都维护了一个键-值的字典,它可以在线程里面的任何地方被访问。你 可以使用该字典来保存一些信息,这些信息在整个线程的执行过程中都保持不变。

  Cocoa  里面,你使用  NSThread    threadDictionary  方法来检索一个  NSMutableDictionary  对象,你可以在它里面添加任何线程需要的键。在  POSIX  里面, 你使用  pthread_setspecific    pthread_getspecific  函数来设置和访问你线程的键 和值。

 6、可连接线 程可以传递一个数据指针或者其他返回值给 pthread_exit 函数。其他线程可以通过 pthread_join 函数来拿到这些数据。

 重要:在应用程序退出时,脱离线程可以立即被中断,而可连接线程则不可以。每个可连接 线程必须在进程被允许可以退出的时候被连接。所以当线程处于周期性工作而不允许被中断的时 候,比如保存数据到硬盘,可连接线程是最佳选择 。参见2

创建可连接线程,唯一的办法是使用  POSIX  线程。POSIX 默认创建的线程是可连接的。为了把线程标记为脱离的或可连接的,使用  pthread_attr_setdetachstate  函数来修改正在创建的线程的属性。在线程启动后, 你可以通过调用  pthread_detach  函数来把脱离线程修改为可连接的。

改变线程的优先级, Cocoa  线程使用  NSThread    setThreadPriority:类方法。   POSIX  线程,使用  pthread_setschedparam  函数。

7、 在你编写线程主体入口的时候第一件事情 就是创建一个自动释放池。

在你线程的主 体入口点安装一个  try/catch  模块,可以让你捕获任何未知的异常,并提供一个合适 的响应。

8、 当在其他线程上面执行 selector 时,目标线程须有一个活动的 run loop。 

 为了给 run loop 添加一个观察者,你可以创建 CFRunLoopObserverRef 不透明类 型,并使用 CFRunLoopAddObserver 将它添加到你的 run loop。Run loop 观察者必须 Core foundation 函数创建,即使是 Cocoa 程序

退出 Run Loop

有两种方法可以让  run loop  处理事件之前退出:
    run loop  设置超时时间
  通知  run loop  停止, 使用  CFRunLoopStop  来显式的停止  run loop


9、 如果多个线程同时运行,信号被传递到任何一个系统挑选的线程。换而言之,信号 可以传递给你应用的任何线程。

在你应用程序里面实现信号处理的第一条规则是避免假设任一线程处理信号

10、 当两个不同 的线程分别保持一个锁(而该锁是另外一个线程需要的)又试图获得另外线程保持的 锁时就会发生死锁。

  活锁和死锁类似,当两个线程竞争同一个资源的时候就可能发生活锁。在发 生活锁的情况里,一个线程放弃它的第一个锁并试图获得第二个锁。一旦它获得第二 个锁,它返回并试图再次获得一个锁。线程就会被锁起来,因为它花费所有的时间来 释放一个锁,并试图获取其他锁,而不做实际的工作。

 避免死锁和活锁的最好方法是同一个时间只拥有一个锁。如果你必须在同一时间 获取多于一个锁,你应该确保其他线程没有做类似的事情

 11、@synchronized  指令是在 Objective-C 代码中创建一个互斥锁非常方便的方法。

作为一种预防措施,@synchronized 块隐式的添加一个异常处理例程来保护代码。

该处理例程会在异常抛出的时候自动的释放互斥锁。这意味着为了使用  @synchronized  指令,你必须在你的代码中启用异常处理

NSRecursiveLock  类定义的锁可以在同一线程多次获得,而不会造成死锁

12、NSConditionLock  对象定义了一个互斥锁,可以使用特定值来锁住和解锁。不要 把该类型的锁和条件(参见“条件”部分)混淆了:lock unlock
而NSCondition:lock wait signal unlock
当多线程需要以特定的顺序来执行任务的时候,你可以使用一个  NSConditionLock  对象,比如当一个线程生产数据,而另外一个线程消费数据。生产 者执行时,消费者使用由你程序指定的条件来获取锁(条件本身是一个你定义的整形 值)。当生产者完成时,它会解锁该锁并设置锁的条件为合适的整形值来唤醒消费者 线程,之后消费线程继续处理数据。

13、 NSDistributedLock  类可以被多台主机上的多个应用程序使用来限制对某些共享 资源的访问,比如一个文件。

 


   

转载于:https://my.oschina.net/dake/blog/196783

猜你喜欢

转载自blog.csdn.net/weixin_34289454/article/details/91586431