• iOS 线程同步 自旋锁 互斥锁


     线程同步的本质是每一条线程的同步都是按顺序的

    =====================================================================================================================

     

    #import "ViewController.h"
    #import <libkern/OSAtomic.h>
    @interface ViewController ()
    @property (nonatomic,assign)  int ticket;
    //@property (nonatomic,assign)  OSSpinLock lock;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
    //    self.lock = OS_SPINLOCK_INIT;
        self.ticket=50;
        [self ticketsTest];
        // Do any additional setup after loading the view.
    }
    -(void)saleTicket{
        //静态创建、则不需要新建属性
        static OSSpinLock lock = OS_SPINLOCK_INIT;
        //若后面是个函数、则需
        /*
        static OSSpinLock lock = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            lock = OS_SPINLOCK_INIT;
        });
         */
        //其他线程执行到这里时,发现锁被加锁了 就会再这排队等待、直到这个锁被打开
        //加锁
        OSSpinLockLock(&lock);
        int ticket = self.ticket;
        sleep(.2);
        ticket--;
        self.ticket=ticket;
        NSLog(@"%d",self.ticket);
        //解锁
        OSSpinLockUnlock(&lock);
    }
    -(void)ticketsTest{
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
    }

    #import "ViewController.h"
    #import <pthread.h>
    @interface ViewController ()
    @property (nonatomic,assign)  int ticket;
    @property (nonatomic,assign)  pthread_mutex_t mutex;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        //初始化锁的属性
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
        //PTHREAD_MUTEX_RECURSIVE 递归锁 同一个线程对同一个锁能多次加锁
        //初始化锁
        pthread_mutex_init(&_mutex, &attr);
        //销毁属性
        pthread_mutexattr_destroy(&attr);
        
        self.ticket=50;
        
        [self ticketsTest];
        
        // Do any additional setup after loading the view.
    }
    -(void)saleTicket{
        pthread_mutex_lock(&_mutex);
        int ticket = self.ticket;
        sleep(.2);
        ticket--;
        self.ticket=ticket;
        NSLog(@"%d",self.ticket);
        pthread_mutex_unlock(&_mutex);
    }
    -(void)ticketsTest{
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
    }
    -(void)dealloc{
        //销毁锁
        pthread_mutex_destroy(&_mutex);
    }
    @end

    pthread_mutex – 条件锁 

    使用场景  两个线程同时执行,其中一个线程要在另外一个线程执行完成之后才能执行

    #import "ViewController.h"
    #import <pthread.h>
    @interface ViewController ()
    @property (nonatomic,assign)  pthread_mutex_t mutex;
    @property (nonatomic, strong) NSMutableArray *data;
    @property (nonatomic,assign)  pthread_cond_t cond;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        //初始化锁的属性
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
        //PTHREAD_MUTEX_RECURSIVE 递归锁 同一个线程对同一个锁能多次加锁
        //初始化锁
        pthread_mutex_init(&_mutex, &attr);
        //销毁属性
        pthread_mutexattr_destroy(&attr);
        //创建条件
        pthread_cond_init(&_cond, NULL);
        
        self.data = [NSMutableArray array];
        
        [self test];
        // Do any additional setup after loading the view.
    }
    //同时执行 删除 添加操作
    -(void)test{
        [[[NSThread alloc]initWithTarget:self selector:@selector(add) object:nil] start];
        [[[NSThread alloc]initWithTarget:self selector:@selector(remove) object:nil] start];
    }
    -(void)add{
        sleep(1);
        pthread_mutex_lock(&_mutex);
        [self.data addObject:@"A"];
        NSLog(@"添加数据");
        //发送信号通知条件能继续往下执行
    //    pthread_cond_signal(&_cond);
        //广播信号 对应的条件能往下继续执行了
        pthread_cond_broadcast(&_cond);
        pthread_mutex_unlock(&_mutex);
        
    }
    -(void)remove{
        NSLog(@"开始删除数据");
        pthread_mutex_lock(&_mutex);
        if (self.data.count==0) {
            //这时候会等待条件、并且打开当前锁、
            //收到条件信号之后会重新加锁并执行后面的代码
            pthread_cond_wait(&_cond, &_mutex);
        }
        [self.data removeLastObject];
        pthread_mutex_unlock(&_mutex);
        NSLog(@"删除数据");
    }
    -(void)dealloc{
        //销毁锁
        pthread_mutex_destroy(&_mutex);
        //销毁条件
        pthread_cond_destroy(&_cond);
    }
    @end

     串行队列也能解决线程同步问题 保证统一时刻只执行一个线程

    #import "ViewController.h"
    @interface ViewController ()
    @property (nonatomic,assign)  int ticket;
    @property (nonatomic, strong) dispatch_queue_t queue;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.queue=dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
        self.ticket=50;
        [self ticketsTest];
        // Do any additional setup after loading the view.
    }
    -(void)saleTicket{
        dispatch_sync(self.queue, ^{
            int ticket = self.ticket;
            sleep(.2);
            ticket--;
            self.ticket=ticket;
            NSLog(@"%d-=%@",self.ticket,[NSThread currentThread]);
        });
    }
    -(void)ticketsTest{
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
        dispatch_async(queue, ^{
            for (int i =0; i<5; i++) {
                [self saleTicket];
            }
        });
    }
  • 相关阅读:
    Apache Jmeter 性能测试
    linux 达梦数据库 命令行 卸载
    vue控制台报错Duplicate keys detected: 'xxxx'. This may cause an update error.解决方案
    springboot报错说 Failed to parse multipart servlet request; nested exception is java.io.IOException
    简单理解Callable接口
    Windows下设置Mongodb用户名密码
    Win10 搭建FTP环境,并使用Java实现上传,下载,删除
    【小组展示】1
    【计网II】
    【密码学】AES
  • 原文地址:https://www.cnblogs.com/ZhangShengjie/p/12275038.html
Copyright © 2020-2023  润新知