- 串行同步
// 串行队列
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_SERIAL);
// 同步执行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行同步1 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行同步2 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行同步3 %@",[NSThread currentThread]);
}
});
- 串行异步
// 串行队列
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_SERIAL);
// 异步执行
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行异步1 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行异步2 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"串行异步3 %@",[NSThread currentThread]);
}
});
- 并行同步
// 并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_CONCURRENT);
// 同步执行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行同步1 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行同步2 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行同步3 %@",[NSThread currentThread]);
}
});
- 并行异步
// 并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_CONCURRENT);
// 异步执行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行异步1 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行异步2 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并行异步3 %@",[NSThread currentThread]);
}
});
- 主队列同步 会死锁
NSLog(@"\n\n**************主队列同步,放到主线程会死锁***************\n\n");
// 主队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 同步执行
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"主队列同步1 %@",[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"主队列同步2 %@",[NSThread currentThread]);
}
});
- 主队列异步
NSLog(@"\n\n**************主队列异步,串行执行***************\n\n");
// 主队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 同步执行
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"主队列异步1 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"主队列异步2 %@",[NSThread currentThread]);
}
});
- 异步处理耗时,回主线程刷新UI
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"异步处理耗时数据 %@",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"主线程刷新UI %@",[NSThread currentThread]);
});
});
- 栅栏函数
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并发异步执行1 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并发异步执行2 %@",[NSThread currentThread]);
}
});
dispatch_barrier_async(queue, ^{
NSLog(@"\n\n**************barrier**************\n\n");
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并发异步执行3 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i = 0; i < 3; i++) {
NSLog(@"并发异步执行4 %@",[NSThread currentThread]);
}
});
- 延时执行
//相对时间
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
NSLog(@"延迟5秒执行");
});
//绝对时间 (NUll表示自动获取当前时区的当前时间作为开始时刻)
dispatch_after(dispatch_walltime(NULL, 5.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
NSLog(@"延迟5秒执行");
});
//设置固定时间,可做定时任务
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
struct timespec time;
time.tv_sec = (NSInteger)[[formatter dateFromString:@"2020-02-02 11:11:11"] timeIntervalSince1970];
//比固定的时间点再晚10秒
dispatch_time_t timer = dispatch_walltime(&time, 10*NSEC_PER_SEC);
dispatch_after(timer, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"2020-02-02 11:11:11 时间延迟10秒后执行");
});
时间单位
#define NSEC_PER_SEC 1000000000ull //每秒有1000000000纳秒
#define NSEC_PER_MSEC 1000000ull //每毫秒有1000000纳秒
#define USEC_PER_SEC 1000000ull //每秒有1000000微秒
#define NSEC_PER_USEC 1000ull //每微秒有1000纳秒
1秒的写作方式可以是
1 * NSEC_PER_SEC
;
1000 * NSEC_PER_MSEC
;
USEC_PER_SEC * NSEC_PER_USEC
- 单例函数
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"程序只执行了一次");
});
- 快速遍历
//这个顺序是随机的,并发的
dispatch_queue_t queue = dispatch_queue_create("com.sf.test", DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"dispatch_apply : %zd---%@",index,[NSThread currentThread]);
});
- 队列函数
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_queue_create(0, 0), ^{
NSLog(@"队列组1:一个耗时操作已完成!");
});
dispatch_group_async(group, dispatch_queue_create(0, 0), ^{
NSLog(@"队列组2:一个耗时操作已完成!");
});
dispatch_group_async(group, dispatch_queue_create(0, 0), ^{
NSLog(@"队列组3:一个耗时操作已完成!");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"队列组:前面的耗时操作都完成了,回到主线程");
});
多网络请求完成模拟
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"https://baidu.com"]];
[request setTimeoutInterval:3];//超时时间
[request setHTTPMethod:@"GET"];
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
NSURLSessionDataTask *task=[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"队列组网络请求1:一个耗时操作已完成!");
dispatch_group_leave(group);
}];
[task resume];
});
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
NSURLSessionDataTask *task=[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"队列组网络请求2:一个耗时操作已完成!");
dispatch_group_leave(group);
}];
[task resume];
});
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
NSURLSessionDataTask *task=[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"队列组网络请求3:一个耗时操作已完成!");
dispatch_group_leave(group);
}];
[task resume];
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"队列组:前面的耗时操作都完成了,回到主线程");
});
- 定时器
__block NSInteger timeOut = 10;
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer,
dispatch_time(DISPATCH_TIME_NOW, 0 * NSEC_PER_SEC),
1 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(timer, ^{
if (timeOut <= 0) {
dispatch_source_cancel(timer);
NSLog(@"定时器停止");
} else {
NSLog(@"执行任务");
timeOut--;
}
});
dispatch_resume(timer);
- 信号量
- (void)main{
self.semaphore = dispatch_semaphore_create(0);
[self semaphorePlus];
[self semaphoreWait];
}
- (void)semaphoreWait{
// 如果信号量的值 > 0,就让信号量的值减1,然后继续往下执行代码
// 如果信号量的值 <= 0,就会休眠等待,直到信号量的值变成>0,就让信号量的值减1,然后继续往下执行代码
NSLog(@"开始等待");
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"等待结束");
}
- (void)semaphorePlus{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5.0 * NSEC_PER_SEC), dispatch_get_global_queue(0, 0), ^{
NSLog(@"延迟5秒执行");
NSLog(@"信号量加1");
dispatch_semaphore_signal(self.semaphore);
});
}
- 设置优先级
dispatch_queue_t myQueue = dispatch_queue_create("com.sf.test", NULL);
dispatch_queue_t globalHightQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
//第一个参数为要设置优先级的queue,第二个参数是参照物,既将第一个queue的优先级和第二个queue的优先级设置一样。
dispatch_set_target_queue(myQueue, globalHighQueue);
GCD相关函数说明
1. Dispatch Queue
:
//各种队列的获取方法
-(void)getQueue{
//主队列的获取方法:主队列是串行队列,主队列中的任务都将在主线程中执行
dispatch_queue_t mainqueue = dispatch_get_main_queue();
//串行队列的创建方法:第一个参数表示队列的唯一标识,第二个参数用来识别是串行队列还是并发队列(若为NULL时,默认是DISPATCH_QUEUE_SERIAL)
dispatch_queue_t seriaQueue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_SERIAL);
//并发队列的创建方法:第一个参数表示队列的唯一标识,第二个参数用来识别是串行队列还是并发队列(若为NULL时,默认是DISPATCH_QUEUE_SERIAL)
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_CONCURRENT);
//全局并发队列的获取方法:第一个参数表示队列优先级,我们选择默认的好了,第二个参数flags作为保留字段备用,一般都直接填0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
2. dispatch_queue_creat
:
//自定义队列的创建方法
-(void)queue_create{
//串行队列的创建方法:第一个参数表示队列的唯一标识,第二个参数用来识别是串行队列还是并发队列(若为NULL时,默认是DISPATCH_QUEUE_SERIAL)
dispatch_queue_t seriaQueue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_SERIAL);
//并发队列的创建方法:第一个参数表示队列的唯一标识,第二个参数用来识别是串行队列还是并发队列(若为NULL时,默认是DISPATCH_QUEUE_SERIAL)
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_CONCURRENT);
}
3. dispatch_set_target_queue
:
-
dispatch_set_target_queue
可以更改Dispatch Queue
的执行优先级dispatch_queue_create
函数生成的DisPatch Queue
不管是Serial DisPatch Queue
还是Concurrent Dispatch Queue
,执行的优先级都与默认优先级的Global Dispatch queue
相同,如果需要变更生成的Dispatch Queue
的执行优先级则需要使用dispatch_set_target_queue
函数。
//使用dispatch_set_target_queue更改Dispatch Queue的执行优先级
-(void)testTargetQueue1{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
//串行队列的创建方法:第一个参数表示队列的唯一标识,第二个参数用来识别是串行队列还是并发队列(若为NULL时,默认是DISPATCH_QUEUE_SERIAL)
dispatch_queue_t seriaQueue = dispatch_queue_create("com.test.testQueue", NULL);
//指定一个任务
dispatch_async(seriaQueue, ^{
//这里线程暂停2秒,模拟一般的任务的耗时操作
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
});
//全局并发队列的获取方法:第一个参数表示队列优先级,我们选择默认的好了,第二个参数flags作为保留字段备用,一般都直接填0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//指定一个任务
dispatch_async(globalQueue, ^{
//这里线程暂停2秒,模拟一般的任务的耗时操作
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
});
//第一个参数为要设置优先级的queue,第二个参数是参照物,即将第一个queue的优先级和第二个queue的优先级设置一样。
//第一个参数如果是系统提供的【主队列】或【全局队列】,则不知道会出现什么情况,因此最好不要设置第一参数为系统提供的队列
dispatch_set_target_queue(seriaQueue,globalQueue);
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
-
dispatch_set_target_queue
除了能用来设置队列的优先级之外,还能够创建队列的层次体系,当我们想让不同队列中的任务同步的执行时,我们可以创建一个串行队列,然后将这些队列的target指向新创建的队列即可。
- (void)testTargetQueue2 {
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_queue_t targetQueue = dispatch_queue_create("com.test.target_queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue1 = dispatch_queue_create("com.test.queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("com.test.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_set_target_queue(queue1, targetQueue);
dispatch_set_target_queue(queue2, targetQueue);
//指定一个异步任务
dispatch_async(queue1, ^{
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
//指定一个异步任务
dispatch_async(queue2, ^{
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
//指定一个异步任务
dispatch_async(queue2, ^{
NSLog(@"----执行第三个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
4. dispatch_after
:
//延时执行,需要注意的是:dispatch_after函数并不是在指定时间之后才开始执行处理,而是在指定时间之后将任务追加到主队列中。严格来说,这个时间并不是绝对准确的,但想要大致延迟执行任务,dispatch_after函数是很有效的。
-(void)dispatch_after{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 2秒后异步追加任务代码到主队列等待执行
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
5. dispatch_once
:
//只执行一次,通常在创建单例时使用,多线程环境下也能保证线程安全
-(void)dispatch_once_1{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"----只执行一次的任务---当前线程%@",[NSThread currentThread]);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
6. dispatch_apply
:
//快速遍历方法,可以替代for循环的函数。dispatch_apply按照指定的次数将指定的任务追加到指定的队列中,并等待全部队列执行结束。
//会创建新的线程,并发执行
-(void)dispatch_apply{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(100, globalQueue, ^(size_t index) {
NSLog(@"执行第%zd次的任务---%@",index, [NSThread currentThread]);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
7. dispatch_group
:
//队列组:当我们遇到需要异步下载3张图片,都下载完之后再拼接成一个整图的时候,就需要用到gcd队列组。
-(void)dispatch_group{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 第一个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 第二个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 第三个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第三个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行最后的汇总任务---当前线程%@",[NSThread currentThread]);
});
//若想执行完上面的任务再走下面这行代码可以加上下面这句代码
// 等待上面的任务全部完成后,往下继续执行(会阻塞当前线程)
// dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
-
dispatch_group_enter
标志着一个任务追加到 group,执行一次,相当于 group 中未执行完毕任务数+1 -
dispatch_group_leave
标志着一个任务离开了 group,执行一次,相当于 group 中未执行完毕任务数-1。 - 当 group 中未执行完毕任务数为0的时候,才会使
dispatch_group_wait
解除阻塞,以及执行追加到dispatch_group_notify
中的任务。
-(void)dispatch_group_1{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_async(queue, ^{
// 第一个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
// 第二个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(queue, ^{
// 第三个任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第三个任务---当前线程%@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行最后的汇总任务---当前线程%@",[NSThread currentThread]);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
8. dispatch_semaphore
:
//信号量
//总结:信号量设置的是2,在当前场景下,同一时间内执行的线程就不会超过2,先执行2个线程,等执行完一个,下一个会开始执行。
-(void)dispatch_semaphore{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//任务1
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"----开始执行第一个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
NSLog(@"----结束执行第一个任务---当前线程%@",[NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
//任务2
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"----开始执行第二个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:1];
NSLog(@"----结束执行第二个任务---当前线程%@",[NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
//任务3
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"----开始执行第三个任务---当前线程%@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
NSLog(@"----结束执行第三个任务---当前线程%@",[NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
9. Dispatch I/O
:
//以下为苹果中使用Dispatch I/O和Dispatch Data的例子
pipe_q = dispatch_queue_create("PipeQ",NULL);
pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM,fd,pipe_q,^(int err){
close(fd);
});
*out_fd = fdpair[I];
dispatch_io_set_low_water(pipe_channel,SIZE_MAX);
dispatch_io_read(pipe_channel,0,SIZE_MAX,pipe_q, ^(bool done,dispatch_data_t pipe data,int err){
if(err == 0)
{
size_t len = dispatch_data_get_size(pipe data);
if(len > 0)
{
const char *bytes = NULL;
char *encoded;
dispatch_data_t md = dispatch_data_create_map(pipe data,(const void **)&bytes,&len);
asl_set((aslmsg)merged_msg,ASL_KEY_AUX_DATA,encoded);
free(encoded);
_asl_send_message(NULL,merged_msg,-1,NULL);
asl_msg_release(merged_msg);
dispatch_release(md);
}
}
if(done)
{
dispatch_semaphore_signal(sem);
dispatch_release(pipe_channel);
dispatch_release(pipe_q);
}
});
10. dispatch_barrier_async
:
//隔断方法:当前面的写入操作全部完成之后,再执行后面的读取任务。当然也可以用Dispatch Group和dispatch_set_target_queue,只是比较而言,dispatch_barrier_async会更加顺滑
-(void)dispatch_barrier_async{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 第一个写入任务
[NSThread sleepForTimeInterval:3];
NSLog(@"----执行第一个写入任务---当前线程%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
// 第二个写入任务
[NSThread sleepForTimeInterval:1];
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
// 等待处理
[NSThread sleepForTimeInterval:2];
NSLog(@"----等待前面的任务完成---当前线程%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
// 第一个读取任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第一个读取任务---当前线程%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
// 第二个读取任务
[NSThread sleepForTimeInterval:2];
NSLog(@"----执行第二个读取任务---当前线程%@",[NSThread currentThread]);
});
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
11. dispatch_suspend
& dispatchp_resume
:
//场景:当追加大量处理到Dispatch Queue时,在追加处理的过程中,有时希望不执行已追加的处理。例如演算结果被Block截获时,一些处理会对这个演算结果造成影响。在这种情况下,只要挂起Dispatch Queue即可。当可以执行时再恢复。
//总结:dispatch_suspend,dispatch_resume提供了“挂起、恢复”队列的功能,简单来说,就是可以暂停、恢复队列上的任务。但是这里的“挂起”,并不能保证可以立即停止队列上正在运行的任务,也就是如果挂起之前已经有队列中的任务在进行中,那么该任务依然会被执行完毕
-(void)dispatch_suspend{
NSLog(@"----start-----当前线程---%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("com.test.testQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
// 执行第一个任务
[NSThread sleepForTimeInterval:5];
NSLog(@"----执行第一个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
// 执行第二个任务
[NSThread sleepForTimeInterval:5];
NSLog(@"----执行第二个任务---当前线程%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
// 执行第三个任务
[NSThread sleepForTimeInterval:5];
NSLog(@"----执行第三个任务---当前线程%@",[NSThread currentThread]);
});
//此时发现意外情况,挂起队列
NSLog(@"suspend");
dispatch_suspend(queue);
//挂起10秒之后,恢复正常
[NSThread sleepForTimeInterval:10];
//恢复队列
NSLog(@"resume");
dispatch_resume(queue);
NSLog(@"----end-----当前线程---%@",[NSThread currentThread]);
}
网友评论