并行和并发的概念
1.并发:
当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
并发代码的不同部分可以“同步”执行。 如下图⬇️
2.并行:
当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
3.综上:
并行_要求_并发,但并发并不能_保证_并行。
GDC的实现
1.通过NSOperationQueue实现
代码:
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//设置队列最大线程数
queue.maxConcurrentOperationCount = 5;
//创建操作A
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
NSLog(@"i=%d",i);
}
}];
//创建操作B
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
for (int j = 0; j < 5; j++) {
NSLog(@"j=%d",j);
}
}];
//操作B依赖于A的结束
[operationB addDependency:operationA];
//添加操作到队列
[queue addOperation:operationA];
[queue addOperation:operationB];
//输出结果
2020-03-10 09:59:16.022357+0800 GDCTest[6828:73114] i=0
2020-03-10 09:59:16.022482+0800 GDCTest[6828:73114] i=1
2020-03-10 09:59:16.022561+0800 GDCTest[6828:73114] i=2
2020-03-10 09:59:16.022632+0800 GDCTest[6828:73114] i=3
2020-03-10 09:59:16.022718+0800 GDCTest[6828:73114] i=4
2020-03-10 09:59:16.022818+0800 GDCTest[6828:73114] j=0
2020-03-10 09:59:16.022901+0800 GDCTest[6828:73114] j=1
2020-03-10 09:59:16.022979+0800 GDCTest[6828:73114] j=2
2020-03-10 09:59:16.023056+0800 GDCTest[6828:73114] j=3
2020-03-10 09:59:16.023133+0800 GDCTest[6828:73114] j=4
2.通过dispatch实现
dispatch_semaphore 信号量
信号量是一个整型值并且具有初始计数值,信号量通常支持两个操作:通知和等待。当信号被通知的时候计数值会增加,当信号量在线程上等待的时候,必要的情况下线程会被阻塞掉,直至信号被通知时计数值大于0,然后线程会减少这个计数继续工作。
GCD中又3个信号量有关的操作:
dispatch_semaphore_create 信号量创建
dispatch_semaphore_signal 发送通知
dispatch_semaphore_wait 信号量等待
@autoreleasepool {
//创建信号量
__block dispatch_semaphore_t sem = dispatch_semaphore_create(0);
//创建队列
dispatch_queue_t queue = dispatch_queue_create("testBlock", NULL);
dispatch_async(queue, ^{
for (int i = 0; i < 5; i++) {
NSLog(@"i=%d",i);
}
//发送通知
dispatch_semaphore_signal(sem);
});
//等待通知
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
for (int j = 0; j < 5; j++) {
NSLog(@"j=%d",j);
}
}
//打印结果
2020-03-10 10:49:36.302193+0800 GDCTest[11935:127572] i=0
2020-03-10 10:49:36.302317+0800 GDCTest[11935:127572] i=1
2020-03-10 10:49:36.302402+0800 GDCTest[11935:127572] i=2
2020-03-10 10:49:36.302491+0800 GDCTest[11935:127572] i=3
2020-03-10 10:49:36.302573+0800 GDCTest[11935:127572] i=4
2020-03-10 10:49:36.302794+0800 GDCTest[11935:127380] j=0
2020-03-10 10:49:36.302877+0800 GDCTest[11935:127380] j=1
2020-03-10 10:49:36.302951+0800 GDCTest[11935:127380] j=2
2020-03-10 10:49:36.303141+0800 GDCTest[11935:127380] j=3
2020-03-10 10:49:36.303285+0800 GDCTest[11935:127380] j=4