zl程序教程

您现在的位置是:首页 >  其它

当前栏目

GCD之信号量机制二

机制 信号量 gcd
2023-09-14 08:57:58 时间

在前面GCD之信号量机制一中介绍了通过信号量设置并行最大线程数,依此信号量还可以防止多线程访问公有变量时数据有误,下面的代码能说明。

1.下面是不采用信号量修改公有变量的值



dispatch_group_t group=dispatch_group_create();

// dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);

 dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 __block int count=1000;

 for (int i=0; i i++) {

 //信号量减1,如果同时开启10个以上的线程,则信号量小于等于0,此时就会阻塞该线程。

// dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

 dispatch_group_async(group, queue, ^{

 int value = (arc4random() % 4) + 6;

 NSLog(@"%d-%d= %d",count,value,count-value);

 count=count-value;

 //每个线程执行减1后通过信号量通知加1,这样始终保持线程在10个之内

// dispatch_semaphore_signal(semaphore);



 2.运行结果如下:

3.声明一个初始值为1的信号量来开启线程修改公有变量时



dispatch_group_t group=dispatch_group_create();

 dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);

 dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 __block int count=1000;

 for (int i=0; i i++) {

 //信号量减1,如果同时开启10个以上的线程,则信号量小于等于0,此时就会阻塞该线程。

 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

 dispatch_group_async(group, queue, ^{

 int value = (arc4random() % 4) + 6;

 NSLog(@"%d-%d= %d",count,value,count-value);

 count=count-value;

 //每个线程执行减1后通过信号量通知加1,这样始终保持线程在10个之内

 dispatch_semaphore_signal(semaphore);



 4.运行结果如下:

可以看到,第一代码段时修改公有变量时不是有序的,第二个代码段才是真正正确的修改顺序。这过程可取款的过程一样,金额是1000,可能在不同的地方同时取款,取款时不可能金额是像第一代码段那样。这个和C#的lock关键字有一样的效果。



使用递增计数器的线程同步工具 —— 信号量,它的原理是什么样子的? 在 JUC 中线程同步器除了 CountDownLatch 和 CycleBarrier ,还有一个叫做 Semaphore (信号量),同样是基于 AQS 实现的。下面来看看信号量的内部原理。
社会主义 从.Net到iOS,在撸的道路上越走越远,工作之余经营着博客园http://www.cnblogs.com/5ishare,欢迎小伙伴(妹子更好)一起交流,谈谈人生理想。作为经常从网上索取免费资料的一员,要有回报回报的思想,也让更多的人少走弯路.