关于GCD线程,个人理解也不是非常的透彻,只是谈一谈自己的看法
GCD是Grand Central Dispatch的简称,简单来说就是中驱调度器.首先,先了解一下基本的概念
串行/并发
任务串行执行就是每次只有一个任务被执行,任务并发执行就是在同一时间可以有多个任务被执行
同步/异步
一个同步函数只在完成了它预定的任务后才返回。一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成。因此,一个异步函数不会阻塞当前线程去执行下一个函数
临界区
就是一段代码不能被并发执行,也就是,两个线程不能同时执行这段代码。这很常见,因为代码去操作一个共享资源,例如一个变量若能被并发进程访问,那么它很可能会变质(译者注:它的值不再可信)。
死锁
所谓的死锁是指它们都卡住了,并等待对方完成或执行其它操作。第一个不能完成是因为它在等待第二个的完成。但第二个也不能完成,因为它在等待第一个的完成。
并发与并行(这个很多人都分不清)(好比说一个是出发,一个是执行一同出发,并比一定能一起走)
并发代码的不同部分可以“同步”执行。然而,该怎样发生或是否发生都取决于系统。多核设备通过并行来同时执行多个线程;然而,为了使单核设备也能实现这一点,它们必须先运行一个线程,执行一个上下文切换,然后运行另一个线程或进程。这通常发生地足够快以致给我们并发执行地错觉虽然你可以编写代码在 GCD 下并发执行,但 GCD 会决定有多少并行的需求。并行要求并发,但并发并不能保证并行。
GCD有几个特性:
1:GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)你只需要告诉他要做什么,比如说单次执行,延迟执行,等等,GCD就会自动执行,完全不需要你去管理线程相关的事情.GCD是基于C语言的线程管理方案,使用者无需过多参与线程的管理,只需要将想要执行的代码,添加到想要添加的调度队列即可
2:GCD会自动利用更多的CPU内核(比如双核、四核)
GCD存在于libdispatch.dylib这个库中,这是程序动态加载的库类,不需要个人手动导入.
(1)用同步的方式执行任务 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);(想好再用,要不别说我坑你)
(2)用异步的方式执行任务 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
同步和异步的区别就在于
- 同步:在当前线程中执行 在当前线程中执行任务,不具备开启新线程的能力.
- 异步:在另一条线程中执行,在新的线程中执行任务,具备开启新线程的能力
在代码中的区别就在于dispatch_sync(同步)和dispatch_async(异步)就是差一个字母.
异步(子线程(优先级,符号))
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
});
异步(主线程())
dispatch_async(dispatch_get_main_queue(), ^{
});
延迟执行线程
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
单次执行在程序运行中只执行一次
static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{
});
定时器发送验证码按钮封装
btn.enabled = NO;
__block int timeout = 60;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0*NSEC_PER_SEC, 0);//每秒执行
dispatch_source_set_event_handler(_timer, ^{
if (timeout<=0) {
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
[btn setTitle:@"发送验证码" forState:0];
NSLog(@"计时结束");
btn.enabled = YES;
});
}else {
int seconds = timeout %60;
NSString *strTime = [NSString stringWithFormat:@"%d", seconds];
dispatch_async(dispatch_get_main_queue(), ^{
if (timeout == 60) {
[btn setTitle:[NSString stringWithFormat:@"60秒重新发送"] forState:0];
}
else{
[btn setTitle:[NSString stringWithFormat:@"%@秒重新发送",strTime] forState:0];
}
});
timeout--;
}
});
dispatch_resume(_timer);
设置线程等待
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
// 创建一个信号量为0的信号(红灯)
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
if (self.captureSession.isRunning == YES) {
[self.photoOutput capturePhotoWithSettings:self.photoSettings delegate:self];
dispatch_semaphore_signal(sema);
}else{
}
// 开启信号等待,设置等待时间为永久
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
});
设置多任务执行回调
dispatch_group_t group = dispatch_group_create();
//填在任务
dispatch_group_enter(group);
//任务执行完成
dispatch_group_leave(group);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"++++++++++全部完成");
});
异步队列任务
//创建一个并发队列
dispatch_queue_t queue = dispatch_queue_create("Compression", DISPATCH_QUEUE_CONCURRENT);
//创建队列组
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
});
dispatch_group_notify(group, queue, ^{
});
网友评论