iOS多线程之GCD

GCD (Grand Central Dispatch) :iOS4 开始引入,使用更加方便,程序员只需要将任务添加到Dispatch Queues 中即可。

Dispatch Queues 中的任务按照FIFO的顺序进行处理,并且,由于加入任务的方式不同,执行分为同步/异步。

Dispatch Groups 可以帮助我们处理如何判断多线程全部执行结束的问题

Dispatch Semaphores 帮助我们控制多任务对有限数量资源的访问

Dispatch Objects 帮助我们对线程队列进行更加细致的控制(挂起、恢复、取消、激活等操作)

Dispatch Once 可以帮助我们确保某个函数只执行一次,可用于单例的实现

下面针对以上内容给出示例代码

1.串行队列,每次只执行一个任务,无论用什么方式加入任务。

//为了清楚表示可以写为DISPATCH_QUEUE_SERIAL,iOS官方文档定义的DISPATCH_QUEUE_SERIAL就是NULL

使用串行队列,任务都是挨个执行,每次只运行一个。

dispatch_queue_t serialQueue=dispatch_queue_create("串行队列", NULL);

dispatch_sync(serialQueue, ^(){

    NSLog(@“同步加入任务-------%@“,[NSThread currentThread]);

});

dispatch_async(serialQueue, ^(){

    NSLog(@“异步加入任务——%@“,[NSThread currentThread]);   

});

2.并行队列,每次执行多个任务

dispatch_queue_t concurrentQueue = dispatch_queue_create(“并行队列”, DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(concurrentQueue, ^(){

    NSLog(@“同步加入任务-------%@“,[NSThread currentThread]);

});

dispatch_async(concurrentQueue, ^(){

    NSLog(@“异步加入任务——%@“,[NSThread currentThread]);   

});

3.用Dispatch Groups实现判断多线程全部执行结束

// 获取全局队列,全局队列是系统提供的并行队列

dispatch_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(@"11111111111");

});

dispatch_group_async(group, queue, ^{

    NSLog(@"22222222222");

});


dispatch_group_async(group, queue, ^{

     NSLog(@"33333333");

});


dispatch_group_notify(group, dispatch_get_main_queue(), ^{

     NSLog(@“以上执行完成后才执行这里!!!”);

});
也可以使用dispatch_group_wait来完成此功能,但是他会阻塞当前线程

4.只执行某个函数一次

static dispatch_once_t onceToken;

for(int i=0;i<5;i++)

{

dispatch_once(&onceToken, ^{

    NSLog(@"only once");

    });

}

5.信号量

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);

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

    

    dispatch_async(queue, ^(){

        

       dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        

        NSLog(@“信号量资源就一个,按顺序执行 :%d", index);

        if(index==5)

        {

         [NSThread sleepForTimeInterval:3];     

        }

      dispatch_semaphore_signal(semaphore); 

    });

}

6.队列的挂起、恢复

 dispatch_queue_t myQueue;

 myQueue = dispatch_queue_create(“队列”, NULL);

 //挂起队列

dispatch_sync(myQueue, ^(){

        NSLog(@“挂起任务之前“);

    });


dispatch_suspend(myQueue);

dispatch_sync(myQueue, ^(){

        NSLog(@“挂起任务之后“);

    });

//恢复队列

dispatch_resume(myQueue);

*****
*****
*****
*****
下面是对GCD API的一些整理,错误指出还请批评指正

/******************************************************dispatch—queue****************************************************/

/* 

功能:将块函数添加到线程队列中异步执行(异步:执行后不管结果直接返回)

参数:queue:指定的队列   block/work 块函数(context:传入block块函数中的参数)

返回值:空

*/

void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

void dispatch_async_f(dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);

/* 

功能:将块函数添加到线程队列中同步执行(异步:执行完成后返回结果)

参数:queue:指定的队列   block/work 块函数(context:传入block块函数中的参数)

返回值:空

*/

void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

void dispatch_sync_f(dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);

/* 

功能:将块函数添加到线程队列中按照迭代次数执行,所有迭代完成后返回结果

参数:iterations:迭代次数  queue:指定的队列   block/work 块函数(context:传入block块函数中的参数)

返回值:空

*/

void dispatch_apply(size_t iterations, dispatch_queue_t queue,

DISPATCH_NOESCAPE void (^block)(size_t));

dispatch_apply_f(size_t iterations, dispatch_queue_t queue,

void *_Nullable context,

void (*work)(void *_Nullable, size_t));


/* 

功能:获取当前执行中的队列

参数:无

返回值:当前队列或者空

*/

dispatch_queue_t dispatch_get_current_queue(void);

/* 

功能:获取主队列

参数:无

返回值:主队列或者空

*/

dispatch_queue_t dispatch_get_main_queue(void)

{

return DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q);

}

/* 

功能:获取全局并发队列

参数:identifier:队列优先级  typedef long dispatch_queue_priority_t;

- DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED

- DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT

- DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY

- DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND


#define DISPATCH_QUEUE_PRIORITY_HIGH 2

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0

#define DISPATCH_QUEUE_PRIORITY_LOW (-2)

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN


  flags:保留供将来使用,输入除了0以外的任何值可能返回空值

返回值:全局队列或者空

*/

dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);



#define DISPATCH_QUEUE_SERIAL NULL  //串行队列

#define DISPATCH_QUEUE_SERIAL_INACTIVE//暂停状态串行队列

dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_SERIAL)

#define DISPATCH_QUEUE_CONCURRENT //并发队列

DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, _dispatch_queue_attr_concurrent)

#define DISPATCH_QUEUE_CONCURRENT_INACTIVE  //暂停状态并发队列

dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_CONCURRENT)


/* 

功能:设置属性值,用于在队列的创建时加入

参数:attr:队列属性值

返回值:队列属性值

*/

dispatch_queue_attr_t dispatch_queue_attr_make_initially_inactive(

dispatch_queue_attr_t _Nullable attr);



#define DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL 

dispatch_queue_attr_make_with_autorelease_frequency( 

DISPATCH_QUEUE_SERIAL, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)


#define DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL

dispatch_queue_attr_make_with_autorelease_frequency(

 DISPATCH_QUEUE_CONCURRENT, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)


dispatch_queue_attr_t dispatch_queue_attr_make_with_autorelease_frequency(

dispatch_queue_attr_t _Nullable attr, dispatch_autorelease_frequency_t frequency);


/* 

功能:创建队列

参数:label:队列附带信息,可有可无  attr:队列属性值  target:目标队列,相当于目标队列计数加一

返回值:引用的队列

*/


dispatch_queue_t dispatch_queue_create(const char *_Nullable label,

dispatch_queue_attr_t _Nullable attr);


dispatch_queue_t dispatch_queue_create_with_target(const char *_Nullable label,

dispatch_queue_attr_t _Nullable attr, dispatch_queue_t _Nullable target)


/* 

功能:获取队列描述信息

参数:label:队列附带信息,可有可无  attr:队列属性值  target:目标队列,相当于目标队列计数加一

返回值:队列附带信息

*/

const char *dispatch_queue_get_label(dispatch_queue_t _Nullable queue);



//dispatch_qos_class_t dispatch_queue_get_qos_class(dispatch_queue_t queue,

int *_Nullable relative_priority_ptr);


/* 

功能:给指定对象设置目标队列

参数:object:目标对象  queue:目标队列

返回值:无

*/

void dispatch_set_target_queue(dispatch_object_t object,

dispatch_queue_t _Nullable queue);


/* 

功能:dispatch类入口函数

参数:无

返回值:无

*/

void dispatch_main(void);


/* 

功能:在指定时间后再目标队列执行block任务

参数:when:时间 queue:目标队列  block/work:要执行的任务  context:传入任务中的参数

返回值:无

*/

void dispatch_after(dispatch_time_t when,

dispatch_queue_t queue,

dispatch_block_t block);

void dispatch_after_f(dispatch_time_t when,

dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);


/* 

功能:给指定队列增加一个阻塞其它异步执行任务的任务

参数:queue:队列  block/work:任务  context:传入任务的参数

返回值:无

*/

void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);

void dispatch_barrier_async_f(dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);

/* 

功能:给指定队列增加一个阻塞其它同步执行任务的任务

参数:queue:队列  block/work:任务  context:传入任务的参数

返回值:无

*/

void dispatch_barrier_sync(dispatch_queue_t queue,

DISPATCH_NOESCAPE dispatch_block_t block);

void dispatch_barrier_sync_f(dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);


/* 

功能:当指定队列键值改变时,或者是所有属性值都释放后,调用销毁函数destructor

参数:queue:队列  key:键名  context:新内容  destructor:销毁函数

返回值:无

*/

void dispatch_queue_set_specific(dispatch_queue_t queue, const void *key,

void *_Nullable context, dispatch_function_t _Nullable destructor);


/* 

功能:获取指定队列特定键内容

参数:queue:队列  key:键名  

返回值:键值

*/

void *_Nullable dispatch_queue_get_specific(dispatch_queue_t queue, const void *key);

/* 

功能:获取当前队列特定键内容

参数: key:键名  

返回值:键值

*/

void *_Nullable dispatch_get_specific(const void *key);


/* 

功能:验证当前块任务运行在指定队列上

参数:queue:队列 

返回值:无

*/

void dispatch_assert_queue(dispatch_queue_t queue)

DISPATCH_ALIAS_V2(dispatch_assert_queue);

/* 

功能:验证当前块任务运行在指定队列上,并且该任务阻塞队列中的其它任务

参数:queue:队列 

返回值:无

*/

void dispatch_assert_queue_barrier(dispatch_queue_t queue);

/* 

功能:验证当前块任务没有运行在指定队列上

参数:queue:队列 

返回值:无

*/

void dispatch_assert_queue_not(dispatch_queue_t queue)

DISPATCH_ALIAS_V2(dispatch_assert_queue_not);




/******************************************************dispatch—group****************************************************/


/* 

功能:创建派遣队列组

参数:无

返回值:队列组

*/

dispatch_group_t dispatch_group_create(void);

/* 

功能:给指定队列添加异步执行任务,将队列加入组

参数:group:队列组 queue:指定队列  block/work:任务  context:传入任务的参数

返回值:无

*/

void dispatch_group_async(dispatch_group_t group,

dispatch_queue_t queue,

dispatch_block_t block);


void dispatch_group_async_f(dispatch_group_t group,

dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);

/* 

功能:等待(阻塞线程)一直到(队列组中所有任务执行结束或者是时间结束)

参数:group:队列组 timeout:时间

返回值:0表示成功,非0.错误

*/

long dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);

/* 

功能:队列组中所有任务执行结束之后,执行新的block 任务

参数:group:任务组 queue:指定队列  block/work:新任务  context:传入任务的参数

返回值:任务组

*/

void dispatch_group_notify(dispatch_group_t group,

dispatch_queue_t queue,

dispatch_block_t block);


void dispatch_group_notify_f(dispatch_group_t group,

dispatch_queue_t queue,

void *_Nullable context,

dispatch_function_t work);


/* 

功能:管理显示队列组中所有任务

参数:group:队列组 

返回值:队列组

*/

void dispatch_group_enter(dispatch_group_t group);

/* 

功能:管理显示队列组中以执行结束的任务

参数:group:队列组

返回值:队列组

*/

void dispatch_group_leave(dispatch_group_t group);


/******************************************************dispatch—semaphore****************************************************/


/* 

功能:创建信号量

参数:value:信号量资源数

返回值:信号量或空(失败)

*/

dispatch_semaphore_t dispatch_semaphore_create(long value);

/* 

功能:等待获取信号量,获取到后开始继续执行,或是时间结束

参数:dsema:信号量 timeout:限定时间

返回值:无

*/

long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

/* 

功能:执行结束,不需要占用资源,释放信号量

参数:dsema:信号量

返回值:无

*/

long dispatch_semaphore_signal(dispatch_semaphore_t dsema);


/******************************************************dispatch—object****************************************************/


/* 

功能:增加队列引用计数

参数:object:操作队列

返回值:无

*/

void dispatch_retain(dispatch_object_t object);

/* 

功能:减少队列引用计数

参数:object:操作队列

返回值:无

*/

void dispatch_release(dispatch_object_t object);

/* 

功能:获取对象应用程序上下文

参数:object:对象

返回值:定义内容或空

*/

void *_Nullable dispatch_get_context(dispatch_object_t object);

/* 

功能:设置指定对象的应用程序上下文

参数:object:对象 context:上下文内容

返回值:无

*/

void dispatch_set_context(dispatch_object_t object, void *_Nullable context);

/* 

功能:设置对象销毁函数,在该对象所有引用释放后,销毁该对象

参数:object:对象 finalizer:销毁函数指针

返回值:无

*/

void dispatch_set_finalizer_f(dispatch_object_t object,

dispatch_function_t _Nullable finalizer);

/* 

功能:激活指定非活动对象

参数:object:对象(一般是线程队列) 

返回值:无

*/

void dispatch_activate(dispatch_object_t object);

/* 

功能:挂起/阻塞指定对象(一般是线程队列)

参数:object:对象 

返回值:无

*/

void dispatch_suspend(dispatch_object_t object);

/* 

功能:恢复指定对象(一般是线程队列)

参数:object:对象 

返回值:无

*/

void dispatch_resume(dispatch_object_t object);

/* 

功能:同步等待一个对象完成操作,或者是直到超出规定时间

参数:object:对象  timeout:限定时间

返回值:0成功,非0失败

*/

long dispatch_wait(void *object, dispatch_time_t timeout);

/* 

功能:在指定对象完成工作后,将一个通知块任务加入指定队列

参数:object:对象  queue:队列 notification_block:通知块

返回值:无

*/

void dispatch_notify(void *object, dispatch_object_t queue,

dispatch_block_t notification_block);

/* 

功能:取消指定对象

参数:object:对象 

返回值:无

*/

void dispatch_cancel(void *object);

/* 

功能:判断指定对象是否被取消

参数:object:对象 

返回值:0表示未取消,其它表示取消

*/

long dispatch_testcancel(void *object);

/* 

功能:已编程方式记录指定对象的调试调度信息

参数:object:对象 

返回值:无

*/

void dispatch_debug(dispatch_object_t object, const char *message, ...);

void dispatch_debugv(dispatch_object_t object, const char *message, va_list ap);



/******************************************************dispatch—once****************************************************/


/* 

功能:只执行任务函数一次

参数:predicate:dispatch_once_t 对象  block/function要执行的任务函数 context:传入的内容

返回值:无

*/

void dispatch_once(dispatch_once_t *predicate,

DISPATCH_NOESCAPE dispatch_block_t block);

void dispatch_once_f(dispatch_once_t *predicate, void *_Nullable context,

dispatch_function_t function);


/******************************************************dispatch—time****************************************************/


/* 

功能:创建时间对象,在指定时间的基础上再添加一段时间

参数:when:时间  delta:时间段(纳秒)

返回值:时间对象

*/

dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);


/* 

功能:创建时间对象,在指定时间的基础上再添加一段时间

参数:when:时间  delta时间段(纳秒)

返回值:时间对象

*/

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

推荐阅读更多精彩内容