GCD

  1. Dispatch是对象。
    2.MRC下dispatch_retain,dispatch_release。不能用retain/release
    3.您可以通过向编译器标志添加-DOS_OBJECT_USE_OBJC=0来禁用基于objective - c的分派对象。
    4.sync和async最大的区别就是会不会立刻返回。async不用等待block完成就继续执行下面的代码。sync必须等待block完成才能继续执行下面的代码。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    sleep(5);
    NSLog(@"1111");
});
dispatch_barrier_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    sleep(10);
    NSLog(@"2222");
});

我们知道创建队列时, attr 属性有三个值可选,nil、DISPATCH_QUEUE_SERIAL(实际上就是 nil) 或 DISPATCH_QUEUE_CONCURRENT。第一个 if 判断中,苹果认为串行队列,或者 NULL 参数更常见,因此 !attr 的值很有可能不为 0,这与上文的结论一致。

第二个判断中,参数几乎有只可能是 DISPATCH_QUEUE_CONCURRENT,因此 attr == DISPATCH_QUEUE_CONCURRENT 这个判断机会不会为 0,依然与 fastpath 的作用一致。

_dispatch_get_root_queue 会获取一个全局队列,它有两个参数,分别表示优先级和是否支持 overcommit。一共有四个优先级,LOW、DEFAULT、HIGH 和 BACKGROUND,因此共有 8 个全局队列。带有 overcommit 的队列表示每当有任务提交时,系统都会新开一个线程处理,这样就不会造成某个线程过载(overcommit)。

这 8 个全局队列的序列号是 4-11,序列号为 1 的队列是主队列,2 是 manager 队列,用来管理 GCD 内部的任务(比如下文介绍的定时器),3 这个序列号暂时没有使用。队列 的 dq_width 被设置为 UINT32_MAX,表示这些队列不限制并发数。

作为对比,在 _dispatch_queue_init 中,并发数限制dq_width为 1

dispatch_queue_t:按照FIFO顺序依次调用提交给它的块。串行队列一次只调用一个块,但是独立队列可以同时调用彼此的块。global concurrent queues以FIFO顺序调用块,但不等待其完成,允许并发调用多个块。系统管理一个线程池,处理分派队列并调用提交给它们的块。从概念上讲,dispatch queue可能有自己的执行线程,队列之间的交互是高度异步的。Dispatch queues是通过调用dispatch_retain和dispatch_release来引用计数的。提交到队列的挂起块也保存对队列的引用,直到它们完成为止。一旦释放了对队列的所有引用,系统就会释放队列。
dispatch_once_t:这种类型的变量必须具有全局作用域或静态作用域。使用这种类型进行自动或动态分配的结果是未定义的。
dispatch_block_t:
dispatch_function_t:使用dispatch_function_t类型作为参数的函数还可以使用指向您提供的上下文数据的指针。当调用调度函数时,指向上下文数据的指针作为参数传递给函数。指向上下文数据的指针未经修改就传递给函数,您有责任确保指针是有效的。

int pthread_key_create(pthread_key_t key, void (destr_function) (void *))
该函数从TSD池中分配一项,将其值赋给key供以后访问使用。如果destr_function不为空,在线程退出(pthread_exit())时将以key所关联的数据为参数调用destr_function(),以释放分配的缓冲区。

方法一:dispatch_get_main_queue
Discussion:提交给主队列的block只能主线程执行。出自GCD源码queue.c文件_dispatch_sync_wait方法注释。第4044行。主队列由系统自动创建,并与应用程序的主线程相关联。与全局并发队列一样,对dispatch_suspend、dispatch_resume、dispatch_set_context等调用在与此函数返回的队列一起使用时不起作用。dq_serialnum是队列序号。
OC

dispatch_queue_t dispatch_get_main_queue(void);
dispatch_queue_t mainQueue = dispatch_get_main_queue();

Swift

class var main: DispatchQueue { get }
let dispatchMainQueue = DispatchQueue.main

方法二: dispatch_get_global_queue
Discussion:返回具有指定服务质量的系统定义的全局并发队列。
方法三: dispatch_set_target_queue
Discussion:
方法四: dispatch_async
Discussion:这个函数是向调度队列提交块的基本机制。对这个函数的调用总是在块被提交后立即返回,从不等待块被调用。目标队列决定对于提交到同一队列的其他块是串行调用还是并发调用该块。相互独立的串行队列被并发地处理。
方法五: dispatch_async_f
Discussion:
OC

typedef void (*dispatch_function_t)(void *_Nullable);
void dispatch_async_f(dispatch_queue_t queue, void *context, dispatch_function_t work);
dispatch_async_f(dispatch_get_main_queue(), (__bridge void * _Nullable)(dispatch_get_main_queue()), asdzxcqwe);
void asdzxcqwe(void *qwe) {
    pthread_setname_np("www");
    printf("sss");
    char *name = NULL;
    pthread_getname_np(pthread_self(), name, 0);
    printf("%s", name);
}

方法六:dispatch_sync
Discussion:向调度队列提交一个块,以便同步执行。与dispatch_async不同,这个函数在块完成后才返回。(就是说block完成之后才能运行下面的代码)调用此函数并以当前队列为目标会导致死锁。块上没有执行Block_copy。
方法:dispatch_barrier_sync
Discussion:调用此函数并以当前队列为目标会导致死锁。
方法:dispatch_barrier_async
Discussion:对这个函数的调用总是在块被提交后立即返回,从不等待块被调用。当barrier块到达私有并发队列的前端时,它不会立即执行。相反,队列等待直到当前执行的块完成执行。这时,barrier块就自己执行了。在barrier块之后提交的任何块在barrier块完成之前都不会执行。您指定的队列应该是您自己使用dispatch_queue_create函数创建的并发队列。如果传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为与dispatch_async函数类似。
方法: dispatch_apply
Discussion:这个方法必须等待block完成后才能返回。
方法: dispatch_after
Discussion:这个函数立即返回。等待到指定的时间,然后异步地向指定的队列添加块。当DISPATCH_TIME_NOW作为参数提交时,效果不如直接调用dispatch_async。
OC

void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);

方法: dispatch_queue_get_label
Discussion:
方法: dispatch_get_specific
Discussion:与执行当前块的调度队列关联的键。键只是作为指针进行比较,从来没有取消引用。不建议直接传递字符串常量。只能在对应queue的block里拿到specific。
OC

dispatch_queue_t queue1 = dispatch_queue_create(queueKey1, DISPATCH_QUEUE_SERIAL);
dispatch_queue_set_specific(queue1, queueKey1, &queueKey1, NULL);
dispatch_async(queue1, ^{
    NSLog(@"7. t当前线程是: %@, 当前队列是: %@ 。",[NSThread currentThread],dispatch_get_current_queue());
     [NSThread sleepForTimeInterval:1];        
});

方法: dispatch_main
Discussion:

dispatch_main();

在main线程终止时如果调用了pthread_exit(),那么此时终止的只是main线程,而进程的资源会为其他由main线程创建的线程保持打开的状态,直到其他线程都终止。而在其他的由main线程创建的线程中pthread_exit并没有这种作用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容