基础知识总结(二)

昨天忙碌了一天没有继续做自己的笔记,今天继续。今天主要是加深一下自己对GCD、NSOperation、NSthread的理解和使用吧。

1.进程和线程的区别?同步异步的区别?并行和并发的区别?

进程、线程的叫法是相对的。每一个应用运行的进程相对于一台电脑、一个手机来说是线程。但对于一个应用来说,我们会在应用的进程里边开辟很多线程,来处理不同的耗时的任务。

进程:有独立的地址空间,一个进程崩溃之后,在保护模式下不会对其他进程产生影响。进程是资源分配的基本单位。

线程:进程中的任务的不同执行路径。线程有自己的堆栈和局部变量,但是没有单独的地址空间。一个线程死掉等同于整个进程死掉。所以多进程的程序比多线程的程序健壮。但是进程之间的切换,资源消耗较大。效率低。

联系:二者都是由操作系统所体会的程序运行的基本单元。系统利用该基本单元实现系统对应用的并发性。进程是线程的容器,代码执行在线程中,进程则作为线程的执行环境。一个程序至少包含一个进程,一个进程至少包含一个线程。一个进程中的所有线程共享当前进程所拥有的资源。

同步:在程序内的调用者发出一个“调用”之后,在没有得到调用结果(CPU返回执行的数据段部分)之前,调用者会一直处于等待的状态,直至结果返回,才会执行下一个语句。换句话说,就是由调用者主动等待这个“调用”的结果。并不会耽误CPU处理其他的事件。

异步:调用者发出“调用”之后,调用会直接返回。没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在“调用”发出后,“被调用者”通过状态、通知来通知调用者,或通过回调函数处理这个调用。

并行:CPU的多核芯同时执行多个任务。

并发:单核CPU交替执行两个任务。

2,线程间通信?

线程间通讯的体现:

(1)一个线程传递数据给另一个线程,如:网络数据的异步线程请求,回归主线程进行赋值,刷新UI。

(2)在一个线程中执行完特定任务之后,转到另一个线程继续执行任务。

线程间通信常用的方法:

(1)NSThread`可以先将自己的当前线程对象注册到某个全局的对象中去,这样相互之间就可以获取对方的线程对象,然后就可以使用下面的方法进行线程间的通信了,由于主线程比较特殊,所以框架直接提供了在主线程执行的方法。

-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;

-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5,2_0);

(2)GCD,一个线程的数据传递给另一个线程。

- (void)touchesBegan:(NSSet*)touches withEvent(UIEvent*)event

{

          dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

          NSLog(@"donwload---%@", [NSThreadcurrentThread]);// 1.子线程下载图片

          NSURL*url = [NSURLURLWithString:@"http://d.jpg"];

          NSData*data = [NSDatadataWithContentsOfURL:url];

          UIImage*image = [UIImageimageWithData:data];

          // 2.回到主线程设置图片

          dispatch_async(dispatch_get_main_queue(), ^{

                    NSLog(@"setting---%@ %@", [NSThreadcurrentThread], image);

                   [self.button setImage:image forState:UIControlStateNormal];

          });

     });

}

3.GCD的一些常用的函数?(group,barrier,信号量,线程同步)

延迟执行任务函数:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

<#code to be executed after a specified delay#>

});

只执行一次的函数

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

<#code to be executed once#>

});

栅栏函数

dispatch_barrier_sync 同步函数,会阻塞线程

dispatch_barrier_async 异步函数,不会阻塞线程

如果所有任务都在同一个并行队列中,并且这个并行队列不是系统自带的全局并行队列,那么在barrier之前添加的任务执行完毕之后才会执行barrier任务。只有barrier任务执行完毕之后才会执行barrier之后添加的任务。

dispatch_barrier_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)

dispatch_barrier_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)

队列的使用

dispatch_group_async(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)

定时器

/*

第一个参数:给那个定时器设置

第二个参数:什么时候启动

第三个参数:间隔多久执行一次

第四个参数:设置精准度:0 代表最高精准(尽量让定时器精准), 大于0的的话代表是在多少秒内接受.

第四个参数存在意义:主要是为了提高程序性能, 设置越大,能减轻CPU的压力

注意:GCD定时器传入的时间都是纳秒

*/

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, <#dispatchQueue#>);

dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, <#intervalInSeconds#> * NSEC_PER_SEC, <#leewayInSeconds#> * NSEC_PER_SEC);

dispatch_source_set_event_handler(timer, ^{

<#code to be executed when timer fires#>

});

dispatch_resume(timer);

信号量

假设现在系统由两个空闲资源可以被利用,但是同一时间却有三个线程进行访问。这个时候就可以方便的利用信号量来解决。

信号量:就是一种可用来控制访问资源的数量的标识,设定了一个信号量,在线程访问资源之前,加上信号量的处理,则可告知系统按照我们指定的信号量数量来执行多个线程。类似锁机制。

函数:

//创建信号量,参数:信号量的初值,如果小于0则会返回NULL

dispatch_semaphore_create(信号量值)

//等待降低信号量

dispatch_semaphore_wait(信号量,等待时间)

//提高信号量

dispatch_semaphore_signal(信号量)

注:正常的使用顺序是先降低然后再提高。两个函数通畅是成对使用。

代码示例:

GCD信号量的使用

4.如何使用队列来避免资源抢夺?

将需要访问同一块资源的任务添加到一个串行队列执行。队列内部可根据需求来决定是否需要异步或者同步。

如果不使用队列,可以添加线程锁。有以下方法:

(1)@synchronized(id anObject)-->最简单的方法

会自动对参数对象进行加锁,保证临界区内的代码线程安全。

@synchronized (<#token#>) {

// 这段代码对其他 @synchronized(self) 都是互斥的

// self 指向同一个对象

<#statements#>

}

截图1

(2)采用NSLock

NSLock对象实现了NSLocking protocol,包含几个方法:

lock 加锁

unlock 解锁

tryLock 尝试请求一个锁,如果失败了,并不会阻塞线程,只是立即返回NO。

lockBeforeDate,在指定的date之前暂时性阻塞线程(如果没有获取锁的话)。如果到期还没有获取锁,线程被唤醒,函数立即返回NO。

(3)NSRecursiveLock,递归锁

NSRecursiveLock,多次调用不会阻塞已获取该锁的线程。

如图这段代码是一个死锁状况。

截图2-死锁
截图3-死锁

替换为NSRecursiveLock试一下,运行结果如图:

截图4-NSRecursiveLock

(4)NSConditionLock,条件锁

NSConditionLock,条件锁,可以设置条件

[lock lockWhenCondition:A条件];

/*表示如果没有其他线程获得该锁,但是该锁内部的condition不等于A条件,它不会得到改锁,等待。如果内部的condition等于A条件,并且没有其他线程获得该锁,则进入代码区,执行代码。同时设置它获得该锁,其他线程都将等待它的代码区执行完毕,直至解锁。*/

[lock unlockWithCondition:A条件];

/*表示解锁,同时把内部的condition设置为A条件*/

(5)NSDistributedLock,分布锁

NSDistributedLock,分布锁,文件方式实现。可以跨进程。用tryLock方法获取锁。用unLock方法释放锁。如果一个获取锁的进程,在释放锁之前挂了。那么锁就一直得不到释放,此时可以通过breakLock强行解锁。

(6)使用信号量,限制访问同一块资源的线程数目

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容