zoukankan      html  css  js  c++  java
  • 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];
            }
        });
    }
  • 相关阅读:
    检测服务器是否开启重协商功能(用于CVE-2011-1473漏洞检测)
    Wireshark解密HTTPS流量的两种方法
    text2pcap: 将hex转储文本转换为Wireshark可打开的pcap文件
    Hibernate框架(五)Hibernate主键生成策略
    HIbernate框架(四)实现添加操作
    Hibernaete框架(三)搭建hibernate环境(重点)
    Hibernate框架(二)什么是orm思想(重点)
    Hibernate框架(一)Hibernate框架是什么?
    拦截器和过滤器的区别
    谈谈java中遍历Map的几种方法
  • 原文地址:https://www.cnblogs.com/ZhangShengjie/p/12275038.html
Copyright © 2011-2022 走看看