ios的gcd dispatch_queue可以理解為是一種線程池化技術(shù)的實(shí)現(xiàn)。
1,全局一共幾個(gè)池?
除了主線程所在的池1個(gè), 其它全局池4個(gè),分別是DISPATCH_QUEUE_PRIORITY_DEFAULT,DISPATCH_QUEUE_PRIORITY_LOW,DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_BACKGROUND
2,一個(gè)池最多支持幾個(gè)線程同時(shí)工作?
64個(gè)
3,多個(gè)池,一共最多幾個(gè)線程同時(shí)工作?
不管幾個(gè)池,總共64個(gè)線程同時(shí)工作,優(yōu)先級(jí)高的池獲得的可活躍線程數(shù)多與優(yōu)先級(jí)低的池,但也不是滴水不漏,低優(yōu)先級(jí)的也能獲得少量活躍線程。

4,自己創(chuàng)建的池跟系統(tǒng)的4個(gè)全局池模式是否一樣?
一樣,也是最多64個(gè)。
5, 串行池可以開多少?
6p上最多到了6248個(gè)池。
池可以開(一個(gè)池對(duì)應(yīng)一個(gè)線程),但是同時(shí)工作的也是最多64個(gè),其余的pending狀。

注:以上測試,[NSProcessInfo processInfo].activeProcessorCount個(gè)數(shù)無關(guān)。
在6p真機(jī)是2個(gè),mac上的模擬器,ios9的4s,ios11的iphone8都是4.貌似模擬器的cpu核數(shù)根pc機(jī)相同。
6,提出疑問?
YY做了一個(gè)隊(duì)列池。管理池的池。
YYDispatchQueuePool的建議是:
默認(rèn)創(chuàng)建activeProcessorCount相同個(gè)數(shù)的串行池(DISPATCH_QUEUE_SERIAL)(2個(gè)或4個(gè),cpu核數(shù)),最多32個(gè)池。
@interface ViewController ()
@end
@implementation ViewController
//////4個(gè)全局池
- (IBAction)do:(id)sender {
NSLog(@"開始了");
//[self test1];
//[self test2];
//[self test3];
// [self test4];
// [self.class testTargetQueue];
[self testTargetQueueIfChangetoMainthread];
}
////多個(gè)池,一共最多幾個(gè)線程同時(shí)工作
// 幾個(gè)池總共64個(gè)線程同時(shí)工作,優(yōu)先級(jí)高的池獲得的可活躍線程數(shù)多與優(yōu)先級(jí)低的池,但也不是滴水不漏,低優(yōu)先級(jí)的能獲得少量活躍線程。
-(void)test3{
//////一個(gè)池,64個(gè)線程同時(shí)工作
dispatch_queue_t queue1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(queue1, ^{
NSLog(@"開始%li", (long)i );
sleep(10);
NSLog(@"結(jié)束%li", (long)i );
});
}
dispatch_queue_t queue2 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(queue2, ^{
NSLog(@"第二個(gè)池開始%li", (long)i );
sleep(10);
NSLog(@"第二個(gè)池結(jié)束%li", (long)i );
});
}
NSAssert(queue1!=queue2, @"asdfasd");
}
/////測試全局池一共有幾個(gè)?
// 全局4個(gè)池+ mainQueue一共5個(gè)
-(void)test2{
dispatch_queue_t queue1 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queue2 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t queue3 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t queue4 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_queue_t queue11 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queue22 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t queue33 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t queue44 =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
NSAssert(queue1==queue11, @"asdfasd");
NSAssert(queue2==queue22, @"asdfasd");
NSAssert(queue3==queue33, @"asdfasd");
NSAssert(queue4==queue44, @"asdfasd");
NSAssert((queue1!=queue2 &&queue1!=queue3&&queue1!=queue4&&queue2!=queue3&&queue2!=queue4&&queue3!=queue4), @"asdfasd");
}
/////測試一個(gè)池最多支持幾個(gè)線程同時(shí)工作?
// 64個(gè)
-(void)test1{
//////一個(gè)池,64個(gè)線程同時(shí)工作
//dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/// 自己創(chuàng)建的池跟系統(tǒng)的4個(gè)全局池模式是否一樣?
///相同
dispatch_queue_t queue= dispatch_queue_create("池1", DISPATCH_QUEUE_CONCURRENT);
for (NSInteger i = 0; i < 100; i++) {
dispatch_async(queue, ^{
NSLog(@"開始%li", (long)i );
sleep(10);
NSLog(@"結(jié)束%li", (long)i );
});
}
}
///池可以開(一個(gè)池對(duì)應(yīng)一個(gè)線程),但是同時(shí)工作的最多64個(gè),其余的pending狀
-(void)test4{
for (NSInteger i = 0; i< 10000; i++) {
dispatch_queue_t queue= dispatch_queue_create([NSString stringWithFormat:@"池%d",i].UTF8String, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"開始%li", (long)i );
sleep(10);
NSLog(@"結(jié)束%li", (long)i );
});
}
}
////不管幾個(gè)池,同時(shí)最多64個(gè)線程工作。
- (void)viewDidLoad {
[super viewDidLoad];
int count = (int)[NSProcessInfo processInfo].activeProcessorCount;
NSLog(@"%d",count);
//
// ///測試最大int32_t
// int32_t i =0;
// while (1) {
// i++;
// if (i<0) {
// NSLog(@"%d", i);
// break;
// }
// }
// int j = i-i ;
// NSLog(@"%d", j);
//
//
//
}
//////dispatch_set_target_queue切換到目標(biāo)線程執(zhí)行代碼
////切換到主線程了
-(void)testTargetQueueIfChangetoMainthread {
dispatch_queue_t targetQueue = dispatch_get_main_queue();
dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
///如果不加,會(huì)導(dǎo)致應(yīng)用崩潰
dispatch_set_target_queue(queue1, targetQueue);
dispatch_async(queue1, ^{
self.view.layer.masksToBounds=YES;
///不改變所有權(quán)
self.view.layer.contents= (__bridge id )([UIImage imageNamed:@"1"].CGImage) ;
UIView *v = [UIView new];
[self.view addSubview:v];
v.backgroundColor=[UIColor redColor];
v.frame=CGRectMake(0, 0, 100, 100);
}) ;
}
//一般都是把一個(gè)任務(wù)放到一個(gè)串行的queue中,如果這個(gè)任務(wù)被拆分了,被放置到多個(gè)串行的queue中,但實(shí)際還是需要這個(gè)任務(wù)同步執(zhí)行,那么就會(huì)有問題,因?yàn)槎鄠€(gè)串行queue之間是并行的。
//那該如何是好呢?
//
//這是就可以使用dispatch_set_target_queue了。
//
//如果將多個(gè)串行的queue使用dispatch_set_target_queue指定到了同一目標(biāo),那么著多個(gè)串行queue在目標(biāo)queue上就是同步執(zhí)行的,不再是并行執(zhí)行。
//總結(jié):dispatch_set_target_queue可以設(shè)置queue的優(yōu)先級(jí),也可以使多個(gè)serial queue在目標(biāo)queue上一次只有一個(gè)執(zhí)行
////最多支持64個(gè)線程并行執(zhí)行
////多個(gè)線程并發(fā)時(shí)保持串行執(zhí)行, 也可以使多個(gè)serial queue在目標(biāo)queue上一次只有一個(gè)執(zhí)行
////切換到目標(biāo)線程執(zhí)行代碼
+(void)testTargetQueue {
dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue4 = dispatch_queue_create("test.4", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue5 = dispatch_queue_create("test.5", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue6 = dispatch_queue_create("test.6", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue7 = dispatch_queue_create("test.7", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue8 = dispatch_queue_create("test.8", DISPATCH_QUEUE_SERIAL);
//
// dispatch_set_target_queue(queue1, targetQueue);
// dispatch_set_target_queue(queue2, targetQueue);
// dispatch_set_target_queue(queue3, targetQueue);
// dispatch_set_target_queue(queue4, targetQueue);
// dispatch_set_target_queue(queue5, targetQueue);
// dispatch_set_target_queue(queue6, targetQueue);
// dispatch_set_target_queue(queue7, targetQueue);
// dispatch_set_target_queue(queue8, targetQueue);
void (^aa)(NSString*s) =^(NSString*S){
dispatch_async(queue1, ^{
NSLog(@"%@ in",S);
[NSThread sleepForTimeInterval:3.f];
NSLog(@"%@ out",S);
});
};
aa(@"1");
aa(@"2");
aa(@"3");
aa(@"4");
aa(@"5");
aa(@"6");
aa(@"7");
aa(@"8");
aa(@"9");
//
// dispatch_async(queue1, ^{
// NSLog(@"1 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"1 out");
// });
// dispatch_async(queue1, ^{
// NSLog(@"1 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"1 out");
// });
// dispatch_async(queue2, ^{
// NSLog(@"2 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"2 out");
// });
// dispatch_async(queue3, ^{
// NSLog(@"3 in");
// [NSThread sleepForTimeInterval:1.f];
// NSLog(@"3 out");
// });
// dispatch_async(queue4, ^{
// NSLog(@"4 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"4 out");
// });
// dispatch_async(queue5, ^{
// NSLog(@"5 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"5 out");
// });
// dispatch_async(queue6, ^{
// NSLog(@"6 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"6 out");
// });
// dispatch_async(queue7, ^{
// NSLog(@"7 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"7 out");
// });
// dispatch_async(queue8, ^{
// NSLog(@"8 in");
// [NSThread sleepForTimeInterval:3.f];
// NSLog(@"8 out");
// });
NSLog(@"asdfa");
}