OC多线程之GCD ----- 2

dispatch_create生成的Queue不管是并行队列还是串行队列,其优先级都是默认优先级

但是可以用dispatch_set_target_queue来改变队列的优先级

dispatch_set_target_queue(原来的队列, 目标优先级队列)

使用这个函数需要获取两个队列,一个是需要变更优先级的队列,一个是指定优先级的队列(指定优先级的队列可以通过get_global获得)

如果多个串行队列优先级相同,那么这些队列里的任务也会串行执行

dispatch_after函数并不能非常精确的在一段时间后执行任务,dispatch_after只是在指定时间后将block插入到队列中,至于什么时候执行要看系统的执行状况

延迟多少触发大家都知道,下面这个代码是利用NSDate生成一个时间,让dispatch在这个时间去执行block,但是这个貌似只能精确到分,没有精确到秒,可能是我代码有问题,原因还早查找中

@implementation NSDate (dis)

-(dispatch_time_t)getDis{

    NSTimeInterval interval;
    double second,subsecond;
    struct timespec time;
    dispatch_time_t milestone;

    interval = [self timeIntervalSince1970];
    subsecond = modf(interval, &second);

    time.tv_sec = second;
    time.tv_nsec = subsecond * NSEC_PER_SEC;
    milestone = dispatch_walltime(&time, 0);

    return milestone;
}

@end

GCD使用过程中应该谨慎使用sync函数,因为稍有不慎就将导致死锁

dispatch_apply函数是asyn和group的关联API,该函数可以执行指定次数的block 但是会阻塞线程(同步执行),见下面的代码

    dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
        NSLog(@"%zu",index);
    });

    NSLog(@"done");

//===============打印结果

2014-06-19 20:58:55.097 efvervq[5840:60b] 0

2014-06-19 20:58:55.097 efvervq[5840:1303] 1

2014-06-19 20:58:55.097 efvervq[5840:3803] 2

2014-06-19 20:58:55.099 efvervq[5840:60b] 4

2014-06-19 20:58:55.097 efvervq[5840:3903] 3

2014-06-19 20:58:55.099 efvervq[5840:1303] 5

2014-06-19 20:58:55.099 efvervq[5840:3803] 6

2014-06-19 20:58:55.099 efvervq[5840:60b] 7

2014-06-19 20:58:55.101 efvervq[5840:3803] 9

2014-06-19 20:58:55.099 efvervq[5840:3903] 8

2014-06-19 20:58:55.102 efvervq[5840:60b] done


//=================

顺序不一,但是在函数外面的done是最后打印的

PS.但是不要搞混了.使用并行队列和sync函数连续添加block时打印出来的书序是0123456789的

我们可以在async函数中使用apply函数,这样能避免阻塞主队列

dispatch_suspend(queue)可以将队列挂起,

dispatch_resume(queue)可以恢复指定的queue,然后系统会继续执行未处理的操作,对已经执行的没有影响

有时需要十分精准的数据安全控制,那么使用dispatch_semaphore可以提供比SerialQueue更加细小颗粒度的访问控制,因为这个是通过信号量控制的

但信号量<0时时不允许访问的

看下面的代码

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    /**
     *  生成dispatch_semaphore

     *  将其计数初始值设为1

     *  保证可访问NSMutableArray类对象的线程同时只能有一个
     */

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

    NSMutableArray *array = [NSMutableArray array];

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

        dispatch_async(queue, ^{
            /**
             *  等待 dispatch_semaphore
             *
             *  一直等待,知道semaphore数值大于等于1
             */

            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            /**
             *  执行到此,信号量为1 然后系统自动减去1,变为0
             * 此时只有执行到这的线程访问array
             */
            [array addObject:[NSNumber numberWithInt:i]];

            /**
             *  访问结束后,给信号量+1.以便其他的线程继续像array中添加对象
             */

            dispatch_semaphore_signal(semaphore);

        });

    }

GCD除了队列之外还有dispatch_source,这个功能可以以相当低的资源消耗来处理文件读写,定时器,信号接收等事件,更多功能可以去查阅苹果的文档

/**
     *  创建一个source
     DISPATCH_SOURCE_TYPE_TIMER 为source的类型(定时器)
     */
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());

    /**
     *  设置时间
     *  延迟15秒后

     * 每2秒重复一次
     *允许延迟1秒
     */
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 15ull * NSEC_PER_SEC), 2ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC);

    // 执行的任务

   __block int a = 0;

    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"wake up");
        a++;
        if (a == 8) {
            dispatch_source_cancel(timer);

        }
    });

    //取消时的操作
    dispatch_source_set_cancel_handler(timer, ^{
        NSLog(@"cancled");
    });

    /**
     *  如果是MRC 需要dispatch_release
     */

    //开始工作
    dispatch_resume(timer);
    

如果你想不让timer重复执行,可以将重复时间设为dispatch_timeForever 或者在set_event_handler里面执行完毕以后cancle掉

set_event_handler里面必须有cancel(或者里面执行的方法有cancel,就是可以搜寻到),否则timer不会执行,你可以自己试试

但是你可以用if(0){cancel}来骗过系统,但是一定不要忘记cancel

OC多线程之GCD ----- 2,布布扣,bubuko.com

时间: 2024-12-10 03:17:35

OC多线程之GCD ----- 2的相关文章

OC多线程之GCD

要了解多线程首先要知道什么是进程,什么是进程? 正在进行中的程序被称为进程,负责程序运行的内存分配 每一个进程都有自己独立的虚拟内存空间 什么是线程: 线程是进程中一个独立的执行路径(控制单元) 一个进程中至少包含一条线程,即主线程 可以将耗时的执行路径(如:网络请求)放在其他线程中执行 创建线程的目的就是为了开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行 线程的优缺点: 优势 (1)充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入“并行运算”状态 (2)将

iOS多线程之GCD小记

iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言的,在在oc中使用时需要包含 #import<pthread.h> 使用这种多线程方案需要手动处理线程的各个状态的转换,也就是要管理线程的生命周期. 2.NSThread 这种多线程方案经过了苹果的封装,是一种面向对象的方案,因此可以直接操控线程对象,相对来说比较便捷,其生命周期也要手动管理 3.

OC开发_课堂笔记——多线程之GCD

一.进程和线程   二.各种队列! 1.GCD:Grand Central Dispatch 2.串行队列(Serial) 你可以创建任意个数的串行队列,每个队列依次执行添加的任务,一个队列同一时刻只能执行一个任务(串行),但是各个队列之间不影响,可以并发执行.每个队列中的任务运行在一个由各自串行队列 维护的独立线程上,一个队列中只有一个线程. 3.并行队列(Concurrent) 并行队列是不允许自己创建的,系统中存在三个不同优先级的并行队列.并行队列依旧按照任务添加的顺序启动任务,但是,后一

(五十五)iOS多线程之GCD

GCD的全称为Grand Central Dispatch,翻译为大中央调度,是Apple开发的一个多线程编程解决方法. 进程和线程的概念: 正在进行中的程序被称为进程,负责程序运行的内存分配,每一个进程都有自己独立的虚拟内存空间. 线程是进程中一个独立的执行路径,即主线程,主线程有1M的栈区,对于耗时的执行路径,可以放在子线程(512K栈区)中执行. Tip:新建线程会消耗内存空间和CPU事件,线程太多会降低系统的运行性能,多线程是通过CPU时分复用实现的. Tip:多线程是为了并发执行多项任

iOS 开发之多线程之GCD

1.GCD(Grand Centrol Dispath) 并行:宏观以及微观都是两个人再拿着两把铁锹在挖坑,一小时挖两个大坑 并发:宏观上是感觉他们都在挖坑,微观是他们是在使用一把铁锹挖坑,一小时后他们挖了两个小坑. 总结:就单个cpu来说,大部分进程是并发进行的,就是一把铁锹,你一下我一下,只是间隔时间较短,用户感觉不到而已. 应用: GCD包括: (1)实际使用中 //dispatch_get_global_queue(0, 0)第一个0是优先级,第二个保留字段 dispatch_async

iOS开发多线程之GCD

- (void)viewDidLoad { [super viewDidLoad]; /*GCD:Grand Central Dispatch 牛逼的中枢调度器,自动管理线程的生命周期(创建 调度 销毁).将任务存放到队列中,GCD会自动将队列中的任务取出,先进先出,放到线程中执行. 同步执行任务:在当前线程中执行 dispatch_sync(dispatch_queue_t queue,dispatch_block_t block) 异步执行任务:在其他线程执行 dispatch_async(

ios多线程之GCD

** dispatch_after 延时操作应用场景 例如:游戏后台需要做一些随机的事件,需要在某个时间后,调用方法! 1> 调用的方法通常是跟UI有关的,例如提示用户等 2> 不了解GCD或者多线程的人,可以直接填空即可 */ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self delay1]; } #pragma mark - 延时操作 /** 在其他线程中调用 dispatch_after */

iOS多线程之GCD学习笔记

什么是GCD 1.全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 2.纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核.四核) GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码 任务和队列 GCD中有2个核心概念 任务:执行什么操作 队列:用来存放任务 GCD的使用就2个步骤,首先确定定制任务(

iOS开发-多线程之GCD(Grand Central Dispatch)

Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过程中只需要将执行的任务并添加到到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务.Dispatch Queue更简单而且在实现符合需求的多线程任务时更有效率.Dispatch  Queue一般来说有三种方式,如下图: Serial执行的时候的先进先出,Concurrent