GCD多线程同步实现锁效果

作者: HHHHHHHHHHD | 来源:发表于2016-08-18 17:58 被阅读445次

多线程同步?这个有什么意义呢。
多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。
先来个概念性的东西,理解下

信号量

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

可以简单理解成线程同步作用和加锁相似。其实同步和加锁是有区别的。只是线程同步的效果和加锁之后的作用一样。具体下一篇会有解释。不废话了,直奔代码

先模拟用户去买票,一共提供三条通道,买票。

没有进行线程同步
线程没有同步

上述是开启三条线程,然后都是同时去对数据进行减减操作。会发现,数据出现异常。那是因为,多条线程同时访问这个数据时候,该线程只是读取到他访问时候的数据,若此时还有其他线程对该数据进行操作的话。则这个数据就会出现异常。

一:GCD中的信号量实现线程同步
- (void)viewDidLoad {
    [super viewDidLoad];
   
    // 实例类person
    self.person = [[Person alloc] init];
    self.person.num = 100;
    
    
    //dispatch_semaphore_create(1) 创建一个信号量,设置信号量的资源数0表示没有资源,调用dispatch_semaphore_wait会立即等待。
    //dispatch_semaphore_signal  发送一个信号会让信号量+1
    //dispatch_semaphore_wait  等待信号会让信号量 —1
    self.semaphore = dispatch_semaphore_create(1);
    
    //模拟三条不同的网络去抢票
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeActionA) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeActionB) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeActionC) userInfo:nil repeats:YES];
    
}

- (void)timeActionA{
       // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personA];
        //发送一个信号,自然会让信号总量加1,
        dispatch_semaphore_signal(self.semaphore); 
    });   
}
- (void)timeActionB{    
    // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personB];
        dispatch_semaphore_signal(self.semaphore);
    });   
}
- (void)timeActionC{   
    // 线程A
 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        [self.person personC];
        dispatch_semaphore_signal(self.semaphore);
    });
}

Person类的实现。

-(void)personA{
    self.num--;
    NSLog(@"A票通道  剩余总票:%ld",(long)self.num);}
-(void)personB{
    self.num--;
    NSLog(@"B票通道  剩余总票:%ld",(long)self.num);
}

-(void)personC{
    self.num--;
    NSLog(@"C票通道  剩余总票:%ld",(long)self.num);   
}
模拟抢票Log
一:GCD分组实现线程同步
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 实例类person
    self.person = [[Person alloc] init];
    self.person.num = 100;
    
    //创建队列组队
    self.group = dispatch_group_create();
    
    
    //模拟三条不同的网络去抢票
    [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(timeActionA) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeActionB) userInfo:nil repeats:YES];
    [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(timeActionC) userInfo:nil repeats:YES];

    
}

- (void)timeActionA{
    
    //进入组
    dispatch_group_enter(self.group);
    //线程放进队列组
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self.person personA];
        //离开组
        dispatch_group_leave(self.group);
    });
}

- (void)timeActionB{    

    //进入组
    dispatch_group_enter(self.group);
    
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        [self.person personB];
        dispatch_group_leave(self.group);
        
    });

}

- (void)timeActionC{
    //进入组
    dispatch_group_enter(self.group);
    
    dispatch_group_async(self.group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        
        [self.person personC];
        dispatch_group_leave(self.group); 
    });
}
线程组模拟线程同步

相关文章

  • GCD多线程同步实现锁效果

    多线程同步?这个有什么意义呢。多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数...

  • iOS面试之多线程模块

    多线程 多线程内容如下: GCD NSOperation NSThread 多线程与锁 1.GCD 同步/异步和串...

  • [iOS面试]第6章 多线程相关面试问题

    本文主讲多线程相关面试问题:包括GCD、NSOperation、NSThread、多线程与锁。 一、GCD 同步/...

  • 关于dispatch_barrier_async和dispatc

    在iOS多线程中,我们可以用GCD的串行队列来实现同步锁的效果。通过在把任务添加到串行队列中来依次执行,达到同步的...

  • 多线程

    GCD NSOperation NSThread 多线程与锁 一、GCD 同步、异步 和 串行、并发 dispat...

  • 多线程

    ios中为我们提供了GCD、NSOpration、NSThread 一、GCD多线程与锁GCD 同步异步、串行、并...

  • iOS面试总结(初级)

    01:iOS推送机制,实现原理02:多线程编程,GCD,锁,同步异步队列03:property 各种关键字,以及...

  • iOS开发经验(19)-多线程

    目录 pthread NSThread GCD NSOperation 线程锁 线程通讯 | 多线程实现方案 ...

  • iOS 多线程

    参考链接 iOS多线程iOS 多线程:『GCD』详尽总结iOS简单优雅的实现复杂情况下的串行需求(各种锁、GCD ...

  • 多线程相关面试问题

    多线程:GCD、NSOperation、NSThread。 一、GCD 1、同步/异步 和 串行/并发(1)、同步...

网友评论

  • brance:self.semaphore 指的是什么呢?

本文标题:GCD多线程同步实现锁效果

本文链接:https://www.haomeiwen.com/subject/zovvsttx.html