您的当前位置:首页正文

GCD的一些测试

2024-12-15 来源:东饰资讯网

如何实现指定线程数目的线程池?

使用信号量

dispatch_queue_t workConcurrentQueue = dispatch_queue_create("cccccccc", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t serialQueue = dispatch_queue_create("sssssssss",DISPATCH_QUEUE_SERIAL);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
for (NSInteger i = 0; i < 10; i++) {
dispatch_async(serialQueue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_async(workConcurrentQueue, ^{
    NSLog(@"thread-info:%@开始执行任务%d",[NSThread currentThread],(int)i);
    sleep(1);
    NSLog(@"thread-info:%@结束执行任务%d",[NSThread currentThread],(int)i);
    dispatch_semaphore_signal(semaphore);});
});
}
NSLog(@"主线程...!");

这样子创建的的线程最多也就是三个。因为信号量初始化的时候写的是3

串行队列的同步异步测试

如下异步给串行队列里面放任务


dispatch_queue_t serialQueue = dispatch_queue_create("sssssssss",DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{ printf("PRINT>>>>1\n"); });
    printf("PRINT>>>>2\n");
    dispatch_async(serialQueue, ^{ printf("PRINT>>>>3\n"); });
    printf("PRINT>>>>4\n");
    

打印结果

第一次运行:

PRINT>>>>2
PRINT>>>>1
PRINT>>>>4
PRINT>>>>3

第二次运行

PRINT>>>>2
PRINT>>>>4
PRINT>>>>1
PRINT>>>>3

换成同步调用串行队列如下代码

dispatch_sync(serialQueue, ^{ printf("PRINT>>>>1\n"); });
    printf("PRINT>>>>2\n");
    dispatch_sync(serialQueue, ^{ printf("PRINT>>>>3\n"); });
    printf("PRINT>>>>4\n");

两次调用结果都是

PRINT>>>>1
PRINT>>>>2
PRINT>>>>3
PRINT>>>>4

所以得出结论,对于串行队列,同步和异步的区别在于,同步会等待这次任务执行完成,异步只会把任务放进队列里,这里任务值得是「block

但是无论是同步还是异步,串行队列的任务执行顺序是固定的,按照放进队列的先后顺序执行的

并行队列的同步异步测试

dispatch_queue_t serialQueue = dispatch_queue_create("sssssssss",DISPATCH_QUEUE_CONCURRENT);

dispatch_sync(serialQueue, ^{ printf("PRINT>>>>1\n"); });

printf("PRINT>>>>2\n");
    
dispatch_sync(serialQueue, ^{ printf("PRINT>>>>3\n"); });

printf("PRINT>>>>4\n");
    

这里同步调用并行队列,结果总是

PRINT>>>>1
PRINT>>>>2
PRINT>>>>3
PRINT>>>>4

所以同步调用并行队列,和同步调用串行队列的结果一致,任务总是一个接一个的执行,要等待上一个任务完成才会执行下一个任务

异步调用并行队列

dispatch_queue_t serialQueue = dispatch_queue_create("sssssssss",DISPATCH_QUEUE_CONCURRENT);

dispatch_async(serialQueue, ^{ printf("PRINT>>>>1\n"); });

printf("PRINT>>>>2\n");

dispatch_async(serialQueue, ^{ printf("PRINT>>>>3\n"); });

printf("PRINT>>>>4\n");
    

每次运行的结果都不一样。顺序没有办法确定。就是所谓异步。

dispatch_barrier_测试

dispatch_async(serialQueue, ^{ printf("PRINT>>>>1\n"); });
    printf("PRINT>>>>2\n");
    
    
  dispatch_barrier_sync(serialQueue, ^{
        NSLog(@"barrier\n");
    });
    
    
    dispatch_async(serialQueue, ^{ printf("PRINT>>>>3\n"); });
    printf("PRINT>>>>4\n");
    

此处 serialQueue 是一个并行队列,方便测试,直接改创建的函数了。

运行结果如下:

PRINT>>>>2
PRINT>>>>1
barrier
PRINT>>>>4
PRINT>>>>3

这里因为调用的是 dispatch_barrier_sync 同步执行的,所以 3 4 总在 barrier 后面。

显示全文