多线程

2020-05-11  本文已影响0人  QG不吃鱼的猫

一、线程 进程

*   一个程序就是一个进程,一个程序的多个任务被称为线程。
*   进程是表示资源分配的基本单元,线程是进程中执行和调度的基本单元。
*   资源分配给进程,同一个进程可以有多个线程,同一个进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储),但是每个线程拥有自己的栈段,栈段又叫做运行时段,用来存储所有的临时变量和局部变量。
*   处理机分配给线程,即真正运行的是线程。线程执行过程中,需要协作同步,不同的进程的线程利用消息通信的方法进行同步。

//最常用的消息通信是 基于 performSelector dispatch_async MachPort 进行主线程和子线程的通信 。
//关于MachPort的细节可以结合runloop再进行讨论。

二、多线程

*  同一时间,CPU只能处理1条线程,多线程并发执行,其实是CPU快速的在多条线程之间进行调度。
*  开启线程需要一定的内存空间,主线程占用1M,子线程占用512KB,如果线程特别多,会占用大量的内存空间,降低程序的性能。

三、任务和队列

队列:这里的队列指执行任务的等待队列,是一种特殊的线形表,采用 FIFO原则。
任务 :执行操作的意思,就是线程中执行的那段代码。

队列包含 :串行队列(包含主队列)、并行队列
任务执行方式 :同步执行、异步执行

组合:

*  串行队列、同步执行 不开启新线程,任务依次执行
*  串行队列、异步执行 开启一个新线程,任务依次执行
*  并行队列、同步执行 不开启新线程,任务依次执行
*  并行队列、异步执行  开启多个新线程,任务并发执行

四、iOS中的多线程

主要有三种,NSThread、NSoperationQueue,GCD

1.NSThread 轻量级别的多线程技术

基本语法

片段1

NSThread *th = [[NSThread alloc] initWithTarget:self selector:@selector(test:) object:@"123"];
th.threadPriority = 1;
th.name = @"new";
[th start];
[th cancel];

[NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self withObject:@"123"];

片段2
* 构建方式:初始化方式、构造器方式
* 如果是初始化方式,需要自己启动(start)和资源销毁(cancel),threadPriority 0~1。
* 如果是构造器方式,会自动启动。
* performSelector NSObject的子类或者对象都可以调用此方法, 
*  waitUntilDone:YES  如果设置为YES就必须等回调方法执行完毕后再执行后面的代码
* afterDelay 会在内部创建一个NSTimer,然后加到当前线程runloop中,如果没有开启runloop,该方法会失效,也就是在子线程中,需要启动runloop。

2.GCD 对比 NSOpreationQueue

1、两者之间的关系
GCD是面向底层C语言的API,NSOprationQueue用GCD封装构建的,是 GCD的高级抽象。
2、两者之间的区别

五、死锁

在串行队列的任务中,执行同步任务,因为串行队列需要等待任务执行结束才能执行下一个任务,所以会造成死锁。

六、栅栏函数 dispatch_barrier_async

使用范例:可以做到多读单写,在写操作中加入barrier。

dispatch_barrier_async和dispatch_barrier_sync 特点
1、两者同样是干预了本队列中任务的执行,都是先执行前面的任务再执行后面的任务。
2、两者之间唯一的区别是,前者不会干预任务的插入,后者必须等待前面的任务执行结束以后才会对后面的任务进行插入。

七、Dispatch Semaphore 信号量

GCD中的信号量是指 Dispatch Semaphore,是持有计数的信号。

提供了三个函数
dispatch_semaphore_create 创建并初始化总量
dispatch_semaphore_signal 发送信号,总量+1
dispatch_semaphore_wait 总量-1,如果总量为0会一直等待。

主要作用:
1同步
2加锁 实现步骤:初始化信号量为1,执行代码段先wait锁住,代码末尾signal放开。

八、延时函数dispatch_after

使用的是dispatch_time_t , 不用考虑runloop是否开启

九、自旋锁和互斥锁

区别:

* 自旋锁会忙等,即在访问被锁资源时,调用者线程不会休眠,而是在不停的循环在那里,知道被锁资源释放锁。
* 互斥锁会休眠,即在访问被锁资源时,调用者会休眠,此时cpu可以调度其他线程工作,知道被锁资源释放锁,此时会唤醒休眠线程。
*自旋锁高效但是消耗cpu,可以在耗时较少的时候使用。
*自旋锁:atomic,OSSpinLock,dispatch_semaphore_t
  互斥锁:pthread_mutex,@synchronized,NSLock,NSConditionLock,NSCondition,NSRecursiveLock(递归锁)
上一篇 下一篇

猜你喜欢

热点阅读