码迷,mamicode.com
首页 > 移动开发 > 详细

iOS开发系列-线程同步技术

时间:2018-08-25 18:41:32      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:.com   方案   get   air   操作   案例   常见   sre   协同   

概述

多线程的本质就是CPU轮流随机分配给每条线程时间片资源执行任务,看起来多条线程同时执行任务。
技术分享图片
多条线程同时访问同一块资源,比如操作同一个对象、统一变量、同一个文件,就会引发数据错乱和数据安全的问题。

多线程引发问题实例

这里我也借助网上两个比较经典的案例,卖票和存取钱。

卖票案例

多个线程同时卖票,同一时间多个线层同时访问票的总数,就会引发数据错乱。
技术分享图片

实例代码

@interface ViewController ()
@property (nonatomic, assign) int tickets;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tickets = 30;
    [self saleTicketTest];
}

- (void)saleTicketWithName:(NSString *)name
{
   int currTicketCount = self.tickets;
    sleep(.2);
    currTicketCount--;
    self.tickets = currTicketCount;
    NSLog(@"当前%@卖了一张,票还剩:%d张", name ,self.tickets);
}

- (void)saleTicketTest
{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{
        for (int i=0; i<10; i++) {
            [self saleTicketWithName:@"A"];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i=0; i<10; i++) {
            [self saleTicketWithName:@"B"];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i=0; i<10; i++) {
            [self saleTicketWithName:@"C"];
        }
    });
}
@end

异常结果:
技术分享图片

存钱取钱案例

技术分享图片

实例代码

#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, assign) int currMoney;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.currMoney = 1000;
    [self moneyTest];
}

- (void)moneyTest
{
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i=0; i<4; i++) {
            [self saveMoney];
        }
    });

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i=0; i<4; i++) {
            [self drawMoney];
        }
    });
}

// 存钱
- (void)saveMoney
{
    int money = self.currMoney;
    sleep(.3);
    money += 100;
    self.currMoney = money;
    NSLog(@"存了100,还剩%d元", self.currMoney);
    
}

// 取钱
- (void)drawMoney
{
    int money = self.currMoney;
    sleep(.3);
    money -= 50;
    self.currMoney = money;
    NSLog(@"取了50,还剩%d元", self.currMoney);
}

异常结果:
技术分享图片

多线程安全隐患的解决方案

开发中解决多线程安全隐患的方案-使用线程同步技术。同步(协同步调,按预定的先后顺序执行)
常见的线程同步技术就是加锁

技术分享图片

iOS中线程同步的方案根据性能优先级排序:

线程同步的方案 需要导入头文件 类别 注意事项
os_unfair_lock <os/lock.h> 互斥锁 iOS10才开始提供,用来替代OSSpinLock
OSSpinLock <libkern/OSAtomic.h> 自旋锁 目前不在安全,可能会出现优先级反转问题
dispatch_semaphore
pthread_mutex
dispatch_queue(DISPATCH_SENTINEL)
NSLock
oNSCondition <os/lock.h>
pthread_mutex(recuresive)
NSRecursiveLock
NSConditionLock
@synchronized

iOS开发系列-线程同步技术

标签:.com   方案   get   air   操作   案例   常见   sre   协同   

原文地址:https://www.cnblogs.com/CoderHong/p/9534713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!