extendgcd函数c语言,GCD详解及实现二 常用API

dispatch_set_target_queue

因为用dispatch_queue_create函数生成的Dispatch Queue不管是Serial Dispatch Queue还是Concurrent Dispatch Queue其优先级都使用与默认优先级Global Dispatch Queue相同执行优先级的线程。变更的Dispatch Queue的执行优先级,则可以使用dispatch_set_target_queue方法,例如,设置在后台执行动作处理的Serial Dispatch Queue,:

dispatch_queue_t mySerialQueue = dispatch_queue_create(“com.set.gcd”,NULL);

dispatch_queue_t myGlobalDispatch = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);

dispatch_set_traget_queue(mySerialQueue,myGlobalDispatch);

注意1、dispatch_set_target_queue函数的第一个参数,不能指定为系统提供的Main Dispatch Queue和Global Dispatch Queue.

##注意2、在多个Serial Dispatch Queue中使用该函数指定目标为某一个Serial Dispatch Queue,那么原本应执行的多个Serial Dispatch Queue,在目标Serial Dispatch Queue上只能同时执行一个处理。

dispatch_after

如果想在指定时间后执行某些处理,则可以使用dispatch_after函数来实现。

dispatch_time_t time =dispatch_time(DISPATCH_TIME_NOW,3ull*NSEC_PER_SEC);

dispatch_after(time,dispatch_get_main_queue,^{

NSLog(@”等待至少三秒。”);

});

需要注意的是,任务只是在指定时间追加处理到Dispatch Queue。因为 Main Dispatch Queue在主线程runloop中执行,所以在比如每隔1/60秒执行的Runloop中,Block最快在三秒后执行,最慢在3s+1/60秒执行。并且如果主线程还有许多大量任务及UI要处理这个时间会更久。因此严格时间要求下不是很适合,大致延迟多久才更适用。

dispatch_time中第一个参数表示指定的时间开始,到第二个参数指定的毫微秒单位后的时间。

其中, DISPATCH_TIME_NOW这表示现在的时间。

1ull是c语言的数值字面量,是显示表明类型时使用的字符串(表示unsigned long long)。NSEC_PER_SEC毫微秒为单位,NSEC_PER_MSEC毫秒

dispatch_time函数常用于计算相对时间,另外还有一个函数 dispatch_walltime用于计算绝对时间。

Dispatch Group

在追加到Dispatch Queue中的多个处理全部结束后想执行结束处理。只使用一个Serial Dispatch Queue可以实现,但是当使用Concurrent Dispatch Queue或同时使用多个Dispatch Queue时,源代码就会变得颇为复杂。这时候Dispatch Group就派上用场了。

如:

disptach_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,queue,^{NSLog(@”bloko”)});

dispatch_group_async(group,queue,^{NSLog(@”blok1”)});

dispatch_group_async(group,queue,^{NSLog(@”blok2”)});

dispatch_group_notify(group,dispatch_get_main_queue(),^{NSLog(@”done”)});

dispatch_release(group);

dispatch_group_async类似dispatch_async,追加Block到指定的Dispatch Queue中,不同之处第一个参数指明了block属于指定的Didpatch Group.

在追加到dispatch_group中处理全部执行结束时,使用dispatch_group_notify函数会将执行的block追加到Dispatch Queue中。不管指定什么样的Dispatch Queue,当执行BLock时,表明group 中全部处理都完成了。

也可以 使用dispatch_group_wait函数仅等待全部处理执行结束。

disptach_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,queue,^{NSLog(@”bloko”)});

dispatch_group_async(group,queue,^{NSLog(@”blok1”)});

dispatch_group_async(group,queue,^{NSLog(@”blok2”)});

dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

dispatch_release(group);

dispatch_barrier_async

dispatch_barrier_async会等待追加到concurrent Dispatch Queue上的并行执行的处理全部结束后,再将指定的处理追加到concurrent Dispatch Queue中。然后等待dispatch_barrier_async函数追加的处理结束后,concurrent Dispatch Queue才恢复为一般的动作,追加到concurrent Dispatch Queue的处理又开始并行执行。这样可实现高效率的数据库访问和文件访问。

dispatch_sync

稍有不慎就造成线程死锁,

如:dispatch_queue_t queue =dispatch_get_main_queue();

dispatch_sync(queue,^{

NSLog(@”Hello”);

});

该线程在主线程执行指定的Block,并等待其执行结束。而其实主线程正在执行这些源代码,所以无法执行追加到Main Dispatch Queue的Block。

#dispatch_apply

dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API。该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等待全部处理执行结束。如:

disptach_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_apply(10,queue,^(size_t index){

NSlog(@”%zu”,index);

});

NSlog(@”done”);

执行结果:4,2,1,3,5,6,8,7,9 done

因为在Global Dispatch Queue中执行处理,所以各个处理执行时间不定,但是输出done肯定是在最后的位置,因为dispatch_apply会等待所有执行结束。第一个参数为重复次数,第二个参数为追加对象的Disptach Queue第三个参数为追加的处理,其中第三个Block为带参数的Block。这样在操作NSArray时,可以不用编写for循环,利用该函数就可以实现如下。

disptach_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_apply([array count],queue,^(size_t index){

NSlog(@”%zu:[email protected],index,[array objectAtIndex:index]);

});

dispatch_suspend/dispatch_resume

dispatch_suspend(queue);挂起指定的Dispatch Queue

dispatch_resume(queue);恢复指定的 Dispatch Queue

这两个函数,对已经执行的处理没有影响,挂起后,追加到 Dispatch Queue中尚未执行的处理在此之后停止执行。而恢复则使得这些处理能够继续执行。

#Dispatch Semaphore

相比较Serial Dispatch Queue和dispatch_barrier_async函数而言,Dispatch Semaphore提供更细粒度的排他控制,Dispatch Semaphore是持有计数的信号,该计数是多线程编程中的计数类型信号。

生成方法:dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

dispatch_semaphore_waith函数等待Dispatch Semaphore的计数值达到大于或者等于1

dispatch_semaphore_signal函数将Dispatch Semaphore的计数值加1.

如:

disptach_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

NSMutableArray *array = [NSMutableArray array];

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

dispatch_async(queue,^{

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

[array addObject:[NSNumber numberWithInt:i]];

dispatch_semaphore_signal(semaphore);

});

}

dispatch_once

保证应用程序中只执行一次指定处理的API,经常出现于初始化代码。

static disptch_once_t pred;

disapatch_once(&pred,^{

//初始化

});

该源代码在多线程和多核CPU中也能保证百分之百安全。

以上介绍了 GCD中常见的API,另外在读取大文件时,可以将文件分成合适大小,使用Global Dispatch Queue并列读取。GCD中提供Dipsatch I/O和Dispatch Data进行处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值