GCD关于队列和函数对于调用线程的影响

原创 2015年07月09日 01:43:26

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,它的推出是为了取代繁琐的NSThread,它能够自动利用更多的CPU的核数,可以自动管理线程的生命周期,将程序员从繁琐复杂的线程管理中解脱出来。利用GCD技术,我们只需要告诉GCD想要执行的任务就行了。

GCD中有两个核心的概念:

  • "队列"

所谓队列则是用来“存放”任务的。队列和线程是两个概念。队列中存放的任务最后都得由线程来执行!队列的原则:先进先出(FIFO/First In First Out)!

队列大致有几种类型:

常见类型:

1.并行队列(Concurrent Dispatch Queue):并行队列中存放的任务是想要按同时执行(不一定可以同时执行哦

创建一个并行队列

 dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);

2.串行队列(Serial Dispatch Queue):串行队列中存放的任务是想要按顺序执行(不一定可以按照顺序执行哦

创建一个串行队列

<span style="font-family:Verdana, Lucida Grande, Arial, Helvetica, sans-serif;">  dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);</span>

特殊类型:

3.主队列:跟主线程相关联的队列,是GCD自带的一种特殊的串行队列,它里面存放的任务都是在主线程中按顺序执行的

主队列只能获取不能创建

 dispatch_queue_t mainQueue = dispatch_get_main_queue();

4.全局并发队列:一般情况下,并发任务都是存放在全局并发队列中!

全局队列也是只能获取不能创建的

 dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);

  • "任务"

所谓任务就是想要做的事情,执行的操作;GCD中的任务定义在block中。

<span style="font-family:Verdana, Lucida Grande, Arial, Helvetica, sans-serif;">void (^myBlock)() = ^{
// 想要做的任务
}</span>

GCD提供了两种执行任务的函数

1.‘同步’执行任务:同步函数不具备开启新线程的能力,它只能当前线程执行block中的代码

 dispatch_sync(dispatch_queue_t queue, ^(void)block)
2.‘异步’执行任务:异步函数具备开启新线程的能力,可以在新的线程中执行任务

 dispatch_async(dispatch_queue_t queue, ^(void)block)

下面我们分别利用代码来验证函数和队列对于线程的使用规则

A.串行队列同步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self serial_queue_with_sync];
}
- (void)serial_queue_with_sync
{
    NSLog(@"%@",[NSThread currentThread]);
     dispatch_queue_t serial_queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serial_queue, ^{
        NSLog(@"串行队列➕同步函数1%@",[NSThread currentThread]);
    });
    dispatch_sync(serial_queue, ^{
        NSLog(@"串行队列➕同步函数2%@",[NSThread currentThread]);
    });
    dispatch_sync(serial_queue, ^{
        NSLog(@"串行队列➕同步函数3%@",[NSThread currentThread]);
    });
    dispatch_sync(serial_queue, ^{
        NSLog(@"串行队列➕同步函数4%@",[NSThread currentThread]);
    });
}

运行结果如下图所示,可以看到串行队列和同步函数只能在当前线程按顺序执行



B.串行队列异步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self serial_queue_with_async];
}
-  (void)serial_queue_with_async
{
    NSLog(@"%@",[NSThread currentThread]);
    //    创建一个串行队列
    dispatch_queue_t serial_queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    //    异步函数
    dispatch_async(serial_queue, ^{
        NSLog(@"串行队列➕异步函数1%@",[NSThread currentThread]);
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"串行队列➕异步函数2%@",[NSThread currentThread]);
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"串行队列➕异步函数3%@",[NSThread currentThread]);
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"串行队列➕异步函数4%@",[NSThread currentThread]);
    });
    dispatch_async(serial_queue, ^{
        NSLog(@"串行队列➕异步函数5%@",[NSThread currentThread]);
    });
}
运行结果如下图所示,可以看到串行队列和异步函数在子线程按顺序执行


C.并发队列同步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self concunrrent_queue_with_sync];
}
- (void)concunrrent_queue_with_sync
{
    NSLog(@"%@",[NSThread currentThread]);
    dispatch_queue_t concunrrent_queue = dispatch_queue_create("concunrrent",DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(concunrrent_queue, ^{
        NSLog(@"并发队列➕同步函数1%@",[NSThread currentThread]);
    });
    dispatch_sync(concunrrent_queue, ^{
           NSLog(@"并发队列➕同步函数2%@",[NSThread currentThread]);
    });
    dispatch_sync(concunrrent_queue, ^{
        NSLog(@"并发队列➕同步函数3%@",[NSThread currentThread]);
    });
    dispatch_sync(concunrrent_queue, ^{
        NSLog(@"并发队列➕同步函数4%@",[NSThread currentThread]);
    });
}

运行结果如下图所示,可以看到并发队列和同步函数在不开启新线程,在当前线程按顺序执行


D.并发队列异步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self concunrrent_queue_with_async];
}
- (void)concunrrent_queue_with_async
{
    NSLog(@"%@",[NSThread currentThread]);
    dispatch_queue_t concunrrent_queue = dispatch_queue_create("concunrrent",DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列1%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
         NSLog(@"异步函数➕并发队列2%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列3%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列4%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列5%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列6%@",[NSThread currentThread]);
    });
    dispatch_async(concunrrent_queue, ^{
        NSLog(@"异步函数➕并发队列7%@",[NSThread currentThread]);
    });
}
运行结果如下图所示;可以观察到异步函数和并发队列会开启新线程,无序的,同时执行任务


E.主队列异步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self main_queue_with_async];
}
- (void)main_queue_with_async
{
     NSLog(@"%@",[NSThread currentThread]);
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"主队列➕异步函数1%@",[NSThread currentThread]);
    });
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"主队列➕异步函数2%@",[NSThread currentThread]);
    });
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"主队列➕异步函数3%@",[NSThread currentThread]);
    });
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"主队列➕异步函数4%@",[NSThread currentThread]);
    });
}
运行结果如下图所示;可以观察到异步函数和主队列不会开启新线程,主线程按顺序执行任务。



F.主队列同步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self main_queue_with_sync];
}
- (void)main_queue_with_sync
{
    NSLog(@"hahaha");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"%@",[NSThread currentThread]);
    });
}
运行结果如下图所示;可以观察到同步函数和主队列会阻塞线程,不能执行任务


G.全局并发队列同步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self global_queue_with_sync];
}
- (void)global_queue_with_sync
{
    NSLog(@"%@",[NSThread currentThread]);
    dispatch_queue_t global_queue = dispatch_get_global_queue(0, 0);
    dispatch_sync(global_queue, ^{
        NSLog(@"全局队列➕同步函数1%@",[NSThread currentThread]);
    });
    dispatch_sync(global_queue, ^{
        NSLog(@"全局队列➕同步函数2%@",[NSThread currentThread]);
    });
    dispatch_sync(global_queue, ^{
        NSLog(@"全局队列➕同步函数3%@",[NSThread currentThread]);
    });
    dispatch_sync(global_queue, ^{
        NSLog(@"全局队列➕同步函数4%@",[NSThread currentThread]);
    });
}
运行结果如下图所示;可以观察到同步函数和全局并发队列不会开启新线程,当前线程按顺序执行任务

H.全局队列异步函数

- (void)viewDidLoad {
    [super viewDidLoad];
    [self global_queue_with_async];
}
- (void)global_queue_with_async
{
    NSLog(@"%@",[NSThread currentThread]);
    dispatch_queue_t global_queue = dispatch_get_global_queue(0, 0);
    dispatch_async(global_queue, ^{
        NSLog(@"全局队列➕异步函数1%@",[NSThread currentThread]);
    });
    dispatch_async(global_queue, ^{
        NSLog(@"全局队列➕异步函数2%@",[NSThread currentThread]);
    });
    dispatch_async(global_queue, ^{
        NSLog(@"全局队列➕异步函数3%@",[NSThread currentThread]);
    });
    dispatch_async(global_queue, ^{
        NSLog(@"全局队列➕异步函数4%@",[NSThread currentThread]);
    });
    dispatch_async(global_queue, ^{
        NSLog(@"全局队列➕异步函数5%@",[NSThread currentThread]);
    });
}

运行结果如下图所示;可以观察到异步函数和全局并发队列会开启新线程,在新开启的线程中同时执行任务



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

GCD(一) ---- 进程、线程、队列、同步、异步 概念区分与使用

进程、线程、队列、同步、异步 概念区分以前不时会使用到多线程,但没有进行过总结;正好目前闲来无事,进行一下归纳,方便以后使用。GCD简介Grand Central Dispatch 简称(GCD)是苹...

GCD队列与线程的思考

首先声明2个串行队列A,B-(void)viewDidLoad { [super viewDidLoad]; //初始化串行队列A,B A = dispatch_qu...
  • gzpqt
  • gzpqt
  • 2015-09-16 15:49
  • 235

多线程 - 07.GCD函数和队列组合示例

1.GCD基本使用(异步函数+并发队列) 可以看到,系统自动给开辟了新的子线程来执行这三个任务,且由于时并发队列,系统开辟了三个子线程 注意:开辟多少个子线程由系统决定,三个任务依次从队列中取出放在不...

GCD线程基础学习资源

  • 2016-08-09 11:03
  • 41KB
  • 下载

Java的重排序影响线程调用顺序

你所认为的程序运行顺序是什么样的呢?是JVM照着程序编写的顺序运行吗?   正确答案是:不是的。

任务队列线程函数,用互斥体保护

#include #include struct job { /* 维护链表结构用的成员。*/ struct job* next; /* 其它成员,用于描述任务。*/ }; /* 等待执行的任务队...

可延迟函数、内核微线程、工作队列

本文研究多个用于在内核环境当中延迟处理的方法(特别是在 Linux 内核版本 2.6.27.14 当中)。 尽管这些方法针对 Linux 内核,但方法背后的理念, 对于系统架构研究具有更广泛的意义。例...

内核 API,第 2 部分:可延迟函数、内核微线程以及工作队列

摘自:http://www.ibm.com/developerworks/cn/linux/l-tasklets/index.html#differences 本文研究多个用于在内核环境当中延迟...

iOS 【Multithreading-GCD 同步/异步函数 和 串行/并发队列 的6种搭配使用及介绍】

★★ 同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication) ★ 所谓同步,就是在发出一个调用时,在没有得到结...

关于多个线程同时调用单例模式的对象,该对象中方法的局部变量是否会受多个线程的影响

关于多个线程同时调用单例模式的对象,该对象中方法的局部变量是否会受多个线程的影响 对于那些会以多线程运行的单例类,例如Web应用中的Servlet,每个方法中对局部变量的操作都是在线程自己独立的内存...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)