当前位置: 首页 > news >正文

深圳政务服务网上大厅西安自动seo

深圳政务服务网上大厅,西安自动seo,wordpress 主题使用,免费做公益网站文章目录 前言1. 你理解的多线程优点缺点 2. atomic 和 nonatomic 的区别及其作用3. GCD的队列类型 - 三种队列类型4. GCD的死锁问题5. 多线程之间的区别和联系6. 进程和线程?进程间的通信方式线程间的通信方式 6. iOS的线程安全手段如何保证 前言 iOS 锁和多线程的…

文章目录

  • 前言
    • 1. 你理解的多线程
      • 优点
      • 缺点
    • 2. atomic 和 nonatomic 的区别及其作用
    • 3. GCD的队列类型 - 三种队列类型
    • 4. GCD的死锁问题
    • 5. 多线程之间的区别和联系
    • 6. 进程和线程?
        • 进程间的通信方式
        • 线程间的通信方式
    • 6. iOS的线程安全手段如何保证

前言

iOS 锁和多线程的总结

1. 你理解的多线程

多线程是同时执行多个线程(子任务)的能力,用于提高程序性能和响应性。它允许在一个程序中并发地处理多个任务。

  • 并发:在一个时间段多个线程同时进行,计算机通过切换不同的线程实现多线程任务。

优点

  1. 大大提高了程序的运行速度。
  2. 使用线程可以把占据时间较长的任务放到后面去处理,从而提升用户的体验。

缺点

  1. 如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。
  2. 更多的线程需要更多的内存空间。

2. atomic 和 nonatomic 的区别及其作用

  1. atomic原子操作:加锁,保证setter和getter存取方法的线程安全(仅仅对setter和getter方法加锁)。因为线程加锁,别的线程访问当前属性的时候会先执行完属性当前的操作。
  • 对同一对象的set和get的操作是顺序执行的。
  • 速度不快,因为要保证操作整体完成。
  • 线程安全,需要消耗大量系统资源为属性加锁。
  • 使用atomic并不能保证绝对的线程安全,因为atomic仅仅是对系统生成的的settergetter方法加锁, 对于绝对保证线程安全的操作,需要使用更高级的方式处理,NSSpinLock, @syncronized 锁保证线程安全。
  1. nanatomic非原子操作,不加锁,线程执行快,但是多个线程访问同一个属性可能产生crash。
  • 不是默认的
  • 速度更快,如果有两个线程访问同一个属性可能造成crash。
  • 非线程安全
  1. atomic与nonatom的主要区别就是系统自动生成的getter/setter方法不一样
  • atomic系统自动生成的getter/setter方法会进行加锁操作。
  • nonatomic系统自动生成的getter/setter方法不会进行加锁操作。

⚠️:atomic修饰的属性,系统生成的 getter/setter 会保证 getset 操作的完整性,不受其他线程影响。比如,线程 A 的 getter 方法运行到一半,线程 B 调用了 setter:那么线程 A 的 getter 还是能得到一个完好无损的对象。

3. GCD的队列类型 - 三种队列类型

  1. The main queue(主线程串行队列)与主线程功能相同,提交到main queue的任务会在主线程中执行。
dispatch_get_main_queue() 来获取
  1. Global queue(全局并发队列) 全局并发队列由整个进程共享,有 高 中(默认是中) 低和后台四个优先级别。
dispatch_get_global_queue() 可以设置优先级
  1. Custom queue(自定义队列) 可以串行,也可以并发。
dispatch_queue_create()

4. GCD的死锁问题

概念:所谓死锁,通常是两个线程A和B都卡住了,A在等B,B在等A,互相等待到值死锁。

  1. .主线程串行队列同步执行任务,在主线程运行时,会产生死锁
NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

分析:

  • dispatch_sync表示是一个同步线程;
  • dispatch_get_main_queue表示运行在主线程中的主队列;
  • 任务2是同步线程的任务。
  • 任务3需要等待任务2结束之后再执行.

为什么造成死锁?

  1. 首先执行任务1,这是肯定没问题的,只是接下来,程序遇到了同步线程,那么它会进入等待,等待任务2执行完,然后执行任务3。但这是主队列,是一个特殊的串行队列,有任务来,当然会将任务加到队尾,然后遵循FIFO原则执行任务。那么,现在任务2就会被加到最后,任务3排在了任务2前面

任务3要等任务2执行完才能执行,任务2又排在任务3后面,意味着任务2要在任务3执行完才能执行,所以他们进入了互相等待的局面。【既然这样,那干脆就卡在这里吧】这就是死锁。

请添加图片描述

  1. 同步异步互相嵌套
// 同步 + 异步 互相嵌套产生死锁
- (void)sync_async {dispatch_queue_t queue = dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL);NSLog(@"1"); // 任务1dispatch_async(queue, ^{NSLog(@"2"); // 任务2dispatch_sync(queue, ^{NSLog(@"3"); // 任务3});NSLog(@"4"); // 任务4});NSLog(@"5"); // 任务5
}

请添加图片描述
分析:首先通过自定义队列创建了dispatch_queue_create函数创建了一个DISPATCH_QUEUE_SERIAL的串行队列。

  1. 执行任务1.
  2. 遇到异步线程,将【任务2、同步线程、任务4】加入串行队列中。因为是异步线程,所以在主线程中的任务5不必等待异步线程中的所有任务完成;
  3. 因为任务5不必等待,所以2和5的输出顺序不能确定;
  4. 任务2执行完以后,遇到同步线程,这时,将任务3加入串行队列;
  5. 又因为任务4比任务3早加入串行队列,所以,任务3要等待任务4完成以后,才能执行。但是任务3所在的同步线程会阻塞,所以任务4必须等任务3执行完以后再执行。这就又陷入了无限的等待中,造成死锁。
    在这里插入图片描述
    主线程无限循环
- (void)async_loop {dispatch_async(dispatch_get_global_queue(0, 0), ^{NSLog(@"1"); // 任务1dispatch_sync(dispatch_get_main_queue(), ^{NSLog(@"2"); // 任务2});NSLog(@"3"); // 任务3});NSLog(@"4"); // 任务4while (1) {}NSLog(@"5"); // 任务5// a打印 4 1 / 1 4 顺序不定   
}

打印结果: 4 1 / 1 4 顺序不定

分析:

  • 先来看看都有哪些任务加入了Main Queue:【异步线程、任务4、死循环、任务5】。
  • 在加入到Global Queue异步线程中的任务有:【任务1、同步线程、任务3】。
  • 第一个就是异步线程,任务4不用等待,所以结果任务1和任务4顺序不一定。
  • 任务4完成后,程序进入死循环,Main Queue阻塞。但是加入到Global Queue的异步线程不受影响,继续执行任务1后面的同步线程。
  • 同步线程中,将任务2加入到了主线程,并且,任务3等待任务2完成以后才能执行。这时的主线程,已经被死循环阻塞了。所以任务2无法执行,当然任务3也无法执行,在死循环后的任务5也不会执行。

最终,只能得到1和4顺序不定的结果。

5. 多线程之间的区别和联系

在这里插入图片描述

GCD和NSOperation

  • GCD的执行效率更高,执行的是由Block构成的任务,是一个轻量级的数据结构,写起来更加方便
  • GCD只支持FIFO队列,NSOperationQueue可以通过设置最大并发数、设置优先级、添加依赖关系来调整执行顺序
  • NSOperation可以跨越队列设置依赖关系,GCD仅仅能通过栅栏等方法才能控制执行顺序
  • NSOperation更加面向对象,支持KVO,也可以通过继承等关系添加子类。
  • 所以如果我们需要考虑异步操作之间的顺序行、依赖关系,比如多线程并发下载等等,就使用NSOperation

GCD 与 NSThread 的区别

  • NSThread 通过 @selector 指定要执行的方法,代码分散, 依靠的是NSObject的分类实现的线程之间的通讯,如果要开线程必须创建多个线程对象。经常只用的是[NSTread current] 查看当前的线程。
  • NSThread是一个控制线程执行的对象,它不如NSOperation抽象,通过它我们可以方便的得到一个线程,并控制它。但NSThread的线程之间的并发控制,是需要我们自己来控制的,可以通过NSCondition实现。
  • GCD 通过 block 指定要执行的代码,代码集中, 所有的代码写在一起的,让代码更加简单,易于阅读和维护,不需要管理线程的创建/销毁/复用的过程!程序员不用关心线程的生命周期

6. 进程和线程?

参考:进程和线程的概念、区别及进程线程间通信
1. 基本概念:

  • 进程是对运行时程序的封装,是系统进行资源调度和分配的基本单位,实现了操作系统的并发。
  • 线程是进程的子任务,是CPU调度和分配的基本单位,用于保障程序执行的实时性,实现进程内部的并发。线程是操作系统可以识别的最小执行和调度单位。每个线程都肚子占用一个虚拟处理器等,每个线程完成不同的任务,但是共享同一地址空间(也就是同样的动态内存,映射文件,目标代码等等),打开的文件队列和其他内核资源。

2. 区别:

  • 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程依赖于进程而存在。
  • 进程是资源分配的最小单位,线程是CPU调度的最小单位
  • 进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。(资源分配给进程,同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。)
  • 进程间不会相互影响 ;线程:一个线程挂掉将导致整个进程挂掉

3. 通信方式

进程间的通信方式

  1. 进程间通信主要包括管道、系统IPC(包括消息队列、信号量、信号、共享内存等)、以及套接字socket。
  2. 信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器,可以用来控制多个进程对共享资源的访问。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

线程间的通信方式

  1. 临界区:通过多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问;
  2. 互斥量Synchronized/Lock采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问
  3. 信号量Semphare:为控制具有有限数量的用户资源而设计的,它允许多个线程在同一时刻去访问同一个资源,但一般需要限制同一时刻访问此资源的最大线程数目。
  4. 事件(信号),Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作进程间通信的方式:

6. iOS的线程安全手段如何保证

参考:iOS中有哪些技术可以保证线程安全?
问:1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件。当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。此时,我们需要用线程锁来解决。

线程数据安全的方法:

  1. natomic原子操作:使用atomic多线程原子性控制,atomic的原理给setter加上锁,getter不会加锁。
  2. 使用GCD实现atomic操作:给某字段的setter方法和getter方法加上同步队列;
- (void)setCount:(NSInteger)newcount
{dispatch_sync(_synQueue, ^{count = newcount;});
}
- (NSInteger)count
{__block NSInteger localCount;dispatch_sync(_synQueue, ^{localCount = count;});return localCount;
}
  • 互斥锁能够有效的防止因多线程抢夺资源造成的数据安全问题,但是需要消耗大量的CPU资源。
  1. 互斥锁: 使用互斥锁可以确保同一时间只有一个线程访问共享资源。例如@synchronized创建互斥锁
@synchronized (self) {// 访问共享资源的代码
}
  1. 自旋锁:自旋锁(Spin Lock):自旋锁一种忙等待的锁,它会不断地尝试获取锁,直到成功为止。在Objective-C中,可以使用os_unfair_lock来创建自旋锁。
  2. 信号量(Semaphore):信量是一种数器,用于控制同时访问某个资源的线程数量。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 访问共享资源的代码
dispatch_semaphore_signal(semaphore);
  1. 串行队列:串行队列(Serial Queue):使用串行队列可以确保任务按顺序执行,从而避多个线程同时访问共享资源。可以使用GCD(Grand Central Dispatch)来创建串行队列。
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serialQueue DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{// 访问共享资源的代码
});
http://www.dinnco.com/news/39599.html

相关文章:

  • 个人网站做淘宝客如何备案360建站和凡科哪个好
  • jsp动态网站开发心得如何免费推广网站
  • 鸿蒙系统app开发东莞网站建设seo
  • 制作手游需要学什么软件福州seo代理计费
  • 网站建设 文章个人代运营一般怎么收费
  • 绵阳做手机网站软文推广发布
  • 企业网站开源公司如何在百度宣传
  • 怎么开一个属于自己的网店百度seo优化及推广
  • 做微信网站的公司百度站长平台论坛
  • v9做的网站被攻击链接吧跳转中国最厉害的营销策划公司
  • 河南焦作有做网站开发的公司吗网站设计公司官网
  • 移动app与网站建设的区别体验营销策略有哪些
  • 网易企业邮箱app下载搜索引擎优化seo论文
  • 河北省建设项目信息网站湖南seo优化排名
  • asp.net做网站头部和尾部_都用什么来实现东莞今天发生的重大新闻
  • 泉州野外拓展网站建设百度网盘搜索引擎入口在哪里
  • b to c网站建设报价站点查询
  • 北京营销型网站建设哪家好西地那非片能延时多久有副作用吗
  • 网站建设酷隆网络优化有前途吗
  • 怎么做网站规划网站关键词搜索排名
  • 空间类网站价格推广软文范例100字
  • 默认的首页文件名一般是福州百度推广排名优化
  • 教你做吃的网站百度投诉中心24小时电话
  • 专做母婴的网站百度推广助手app
  • 国内外优秀设计网站seo诊断报告
  • 手机网站图片切换搜索关键词排名优化软件
  • 慈溪哪点有学做网站的做网站的流程与步骤
  • 百度百科入口seo外包推广
  • 营销型网站建设的意义论坛推广网站
  • 精品课程网站建设的背景及意义百度seo怎么收费