GCD 之 同步 异步 并发

1.

1     dispatch_async(dispatch_get_global_queue(0, 0), ^{
2         // 处理耗时操作的代码块...
3
4         //通知主线程刷新
5         dispatch_async(dispatch_get_main_queue(), ^{
6             //回调或者说是通知主线程刷新,
7         });
8
9     });  

dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。

dispatch_get_global_queue(0, 0),指用了全局队列。

一般来说系统本身会有3个队列。

global_queue,current_queue,以及main_queue.

获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低

#define	DISPATCH_QUEUE_PRIORITY_HIGH 	 2
#define	DISPATCH_QUEUE_PRIORITY_DEFAULT  0
#define	DISPATCH_QUEUE_PRIORITY_LOW 	(-2)

处理完事物后,需要将结果返回给或者是刷新UI主线程,同样,和上面一样,抓取主线程,程序块操作

2. GCD之并发概念

其实对于编程中,我们一直提及到的几个概念,同步,异步,并发,锁等。

有时觉得一下子还真说不清。

下面我们以上面提到的图片加载来看下这3个概念我的理解

1同步:

   for (int i = 0 ; i < 10; i++) {

         UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
          [myImgV[i] setImage:img];

    }

假设我要加载10个图片,我现在拥有这些图片的资源地址,保存在一个数组中。

我们先以获取第一张图片来举例:

同步执行的概念就是,我获取完第一张图片的,

执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。

如果第一句返回的时间需要10秒,那我程序的响应就仿佛一直卡在这里一样,我无法进行其他操作。必须等它返回!!

因此,同步的一个很好理解的感念就是,一步走到黑。

2.异步

  for (int i = 0 ; i < 10; i++) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
        // 处理耗时操作的代码块...
         UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
        //通知主线程刷新
        dispatch_async(dispatch_get_main_queue(), ^{
            //回调或者说是通知主线程刷新,
              [myImgV[i] setImage:img];
        });

    });

看了这代码,我们会说,异步操作那个假设还是要10秒啊,总体看来,执行一张图片的时间加载还是要在10秒左右啊,

貌似异步没什么鸟用么。但是,别忽略了其中一点,也黑丝核心的一点,此时我们图片获取操作放在里一个线程队列里,

此刻,虽然我们看着图片的加载还是需要10秒才会出来,但是,在这10秒期间,我们的UI主线程是可以操作的,比如界面上有个按钮,你是可以按的

而不是如上面的同步,在10面期间,我是只能干等着,什么都做不了。

异步的核心概念就是一个新线程,一个消息回调通知。

3. 并行

我们还是以上代码为例。前面我强调了,我们只看一张图片的加载,现在,回到我们第一眼看到代码的思维上去,

一个for循环。其实上面代码过后,我是创建了10个异步线程。

好吧,到此,我们应该明白这三个概念了。

同步,其实我前面的例子举得有些局限,就是这个例子本身就说明不需要同步执行,然后给大家大感觉是

同步是编程中一个忌讳点一样,其实不然,很多时候。我们真是需要同步来做一些限制(比如线程中提出的同步锁?听着就感觉有用么

虽然可能并不如我们想的那样的运用同步,但是至少说明这个概念同样是有用的)

我还是以刚才那个加载图片为例子,来个简单的说明如何运用同步的好处。

当然,我只是模拟一个同步的情况。

假设我们现在图片的加载是这样的,图片本身为在加载前是一个默认的图片,上面写着,点击我加载,点击后会调用网络加载方法,然后图片显示加载中,

然后我们双击图片时(当然,理论上是在加载完后)读取图片网络图片放大,好吧,到这里应该能想到要表达的情况了。

整个流程应该是点击图片->加载->双击查看。那如果成了点击->加载中(以返回了图片的作者和信息)-》双击图片(通过前面请求返回的大图链接显示大图)-》

完全加载返回(返回了大图链接)。此时我们看不到图像的大图了。因为我们操作在返回前了,也就是说,

很多时候,我们下一个动作的操作必须需要用到前面一个操作的数据时,我们会给他做认为的同步编程,比如加个按钮锁。

这是我们又会疑惑道,下一个执行需要用到前一个执行的,那第一个例子中的for循环的第二句不是要用到么,这么说

他们必须要同步啊,如果你这么想了,好巧,我们想到一块去了~

但是,注意,前面我们到的异步是为了解决我点击其他按钮的操作,而不是说更新UI操作。下载和更新UI操作在我们看来必须是同步的

这是对的,但是那种做导致了系统本身一些监听事件监听到点击处理在那个请求之后了,这边的加载图片其实要看成一次事件执行,

因为对于事件的这一抽象单元,其实是一种可人为定义的宽广度。

也就是说,一次数据获取和图像填充,其实算是一个图像获取加载事件,事件可以说包含两个单元,加载和填充。

而整个这个事件对于我们点击其他按钮并无关系,那么也就说明了无需同步。

有道理啊,但是若果我们要点击这个图片呢,也就是回到刚才那个可以双击的假设。

此处也许我么又忽略了一点为什么加载中我们能点击双击呢,也就这样的假设是获取图片已经做了异步,但是我们下一步操作又是需要同步的

因此做了人为的同步锁定。

好了,说的太多了,当时至少我们明白两点

异步可能是为了反正耗时操作造成的主线程堵塞,

同步是为了解决一些不必要错误和麻烦。也许到这里,我们脑中会联想到的所谓的线程安全性。

其实同步以及同步锁,却是应该是考虑到这样的不必要和不安全因素。

最后在简单阐述下异步和并发关系。

其实看了上面说的,异步只是提供了一种多线程处理的概念,

并发是更像是异步的一种大规模实现。

就好比说,异步提出了可以用小弟去收保护费,收完了告诉并交给自己,而我在期间做其他要做的事。

并发突然想到,异步这个很有道理啊,那我有4个地方要收,一个小弟去收,虽然我还是可以闲着做其他的事,

但是小弟跑四个地方,我拿到钱所需要的时间还是和我自己去收一样的,只不过我不用那么费劲了,还能做其他事了。

因此,并发觉得应该派四个小弟去,因为每个场地的保护费各不相干的。(刚看了个纽约黑帮~)。

因此说,异步解决了线程堵塞,而并发则是在异步的基础上,提高了符合特性事件的处理时间效率。

当然,如果10个图片本身相互间是没什么联系,但是,最后一个事件需要处理计算这10个图片的总容量值。

那么可以用 dispatch_group_async。

具体就看文档吧。

总体来说,看了iosGCD这块,一是让我熟悉了block编程特性,还有是熟悉如何使用ios提供的GCD特性

来完成多线程编程。

时间: 2024-08-28 10:08:45

GCD 之 同步 异步 并发的相关文章

【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例(转载)

(1)GCD实现的同步异步.串行并行. ——同步sync应用场景:用户登录,利用阻塞 ——串行异步应用场景:下载等耗时间的任务 /** * 因为是异步,所以开通了子线程,但是因为是串行队列,所以只需要开通1个子线程(2),它们在子线程中顺序执行.最常用. */ -(void)gcdDemo1{ dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL); for

GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例

转:http://www.tuicool.com/articles/NVVnMn (1)GCD实现的同步异步.串行并行. ——同步sync应用场景:用户登录,利用阻塞 ——串行异步应用场景:下载等耗时间的任务 /** * 因为是异步,所以开通了子线程,但是因为是串行队列,所以只需要开通1个子线程(2),它们在子线程中顺序执行.最常用. */ -(void)gcdDemo1{ dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gc

C# 【一】进程 , 线程 , 微线程 , 同步 , 异步 , 并发 , 并行 , 阻塞 , 非阻塞

一 理解篇 前言 本文仅仅用作借鉴使用,作者刚入行不久,所以请不小心看到这篇文章的朋友,手下留情. 本文以小故事的形式进行叙述,逻辑不通之处.请理解. 如有错误 ,欢迎指出. 谢谢.                                                           最后修改时间:2019-01-25 1.0.0 进程 老刘是一个软件公司的老板,公司下有两个部门,产品设计部门(产品进程)和研发部门(研发进程),产品设计部门在一楼,研发部门在二楼(独立地址空间).

同步,异步,串行队列,并发队列,全局队列,主队列等概念的总结

同步,异步,串行队列,并发队列,全局队列,主队列等概念的总结 在GCD函数中, 我们常常碰到同步,异步,串行队列,并发队列,全局队列,主队列等概念,而这些概念又常常组合在一起, 十分头疼, 这篇文章就来梳理一下这些烦人的概念. 不想看长篇大论的, 直接看文章末尾的表格即可! 在此之前, GCD中还涉及到两个十分重要的概念, 就是任务和队列 任务(Task): 你需要执行的操作 队列(Queue): 存放任务的容器 GCD中两个重要的函数, 一个同步执行, 一个异步执行 dispatch_asyn

1. 关于GCD的使用(串并行队列和同步异步函数的问题)

/*------------------------------ GCD使用 1.队列和任务------------------------------------------*/ 重点:1."串行队列"? "并发队列"? 2.block? { 1.GCD(Grand Central Dispatch) ---- '牛逼的中枢调度器'! // C语言框架 / 自动管理线程的生命周期(创建/释放) 推出GCD的目的:取代NSThread! 为"多核"

使用ab.exe监测100个并发/100次请求情况下同步/异步访问数据库的性能差异

ab.exe介绍 ab.exe是apache server的一个组件,用于监测并发请求,并显示监测数据 具体使用及下载地址请参考:http://www.cnblogs.com/gossip/p/4398784.html 本文的目的 通过webapi接口模拟100个并发请求下,同步和异步访问数据库的性能差异 创建数据库及数据 --创建表结构 CREATE TABLE dbo.[Cars] ( Id INT IDENTITY(1000,1) NOT NULL, Model NVARCHAR(50) 

iOS-线程之GCD方式---之同步异步和串行队列并行队列之间的关系

GCD方式是Apple官方推荐实现多线程的方式 但在这之前必须理清楚同步,异步,串行队列,并行队列之间的概念. 同步:即当前的执行程序块不会创建一个新的线程,只能在当前线程中执行. 异步:会在当前的线程之外创建一个新的线程,并在新的线程中执行代码块. 首先声明一点,队列是用来存放即将执行的线程体的. 串行队列:串行队列中的线程满足FIFO(First In First Out),并且只有在先出的线程执行完,后续的线程才能出队列执行.(很可能造成APP的假死状态) 并行队列:并行队列也满足FIFO

半同步/半异步并发模式进程池实现

半同步/半异步并发模式:父进程监听到新的客户端连接请求后,以通信管道通知进程池中的某一子进程:"嘿,有新的客户连接来了,你去accept,然后处理下!",从而避免在进程间传递文件描述符.这种模式中,一个客户连接上的所有任务始终有同一个进程来处理. 具体细节,尽在代码中: #ifndef PROCESSPOOL_H #define PROCESSPOOL_H #include <sys/types.h> #include <sys/socket.h> #inclu

进程 线程 多线程 并发 同步异步

进程 线程 多线程 并发 同步异步 很多人对进程,线程,多线程,并发,同步,异步等概念感到困惑,这都是大学没好好听课的缘故啊.咱在这里帮感到概念给感到困惑的同学复习下. 程序 程序用来描述计算机所完成的独立功能,并在时间上严格地按前后次序相继地进行计算机操作序列集合,是一个静态概念. 进程 并发执行的程序在执行过程中分配和管理资源的基本单位.是一个动态的执行过程. 进程的静态描述 进程控制块PCB 有关程序段 该程序员对齐进行操作的数据结构集 进程控制块PCB 进程控制块PCB是系统管制进程存在