zoukankan      html  css  js  c++  java
  • C5-信号量与PV操作(iOS篇-细说信号量)

    一.概述

    二.核心

    2.1 同步机制的概念.为什么叫同步(掌握)?

    信号量是一种同步机制, 之所以叫做同步机制, 是因为把进程互斥看成一种特殊的同步.它即解决同步问题, 又解决互斥问题

    2.2 信号量和P, V操作

    信号量定义: 由一个值和一个对列组成.

    strut semaphore {

    int count; // 信号量的值

    queueType queue; // 挂载在这个信号量上的进程, 用对列保存这些进程

    }

    解说(掌握):

    所谓的信号量就是一个特殊的变量, 用于进程间传递信息的一个整数值.上面的定义并没错, 因为其也包好了信号量是个整数值这层定义.

    对信号量可以实行的操作: 初始化, P(test, 测试操作), V(increment, 增加操作).在实际编程中, P又称为down, semWait. V又称为up, semSignal.

    P的定义如下, s代表信号量变量, 为了方便iOS中的学习, P统一换成semWait. V换成semSignal.

    P(s) {

    s.count = s.count - 1;

    if (s.count < 0) {

      该进程状态置为阻塞态.
    
      将该进程插入相应的等待对列s.queue末尾.
    
      CPU重新调度;
    

    ​ }

    }

    P操作主要做两件事(掌握):

    1. 将信号量的值减1.
    2. 判断信号量的值是否小于0, 是则阻塞当前进程, 否则当前进程扔可继续运行.(具体的阻塞细节: 2.1 该进程状态设置为阻塞态. 2.2 将该进程插入相应的等待对列s.queue末尾. 2.3CPU重新调度)

    P的总结(掌握):

    所以P操作, 即semWait具有阻塞进程的能力.P操作之后的代码"具备"阻塞能力.

    V(s) {

    s.count ++;

    if (s.count < = 0)

    {

      唤醒相应等待队列s.queue中等待的一个进程;
    
       改变其状态为就绪态,并将其插入就绪队列;
    

    }

    }

    V(掌握):

    主要做的也是两件事件: 1.将信号量加1. 2.判断信号量的值是否是<= 0, 是的话则表示当前进程已经出了临界区.唤醒等待对列s.queue中的等待的一个进程, 改变其状态为就绪态,并将其添加到就绪对列, 等待CPU调度.

    V的总结(掌握):

    V操作也只有在出临界区后才调用. 所以V操作之后, 其之前的代码对于该进程就不具备阻塞能力.让当前进程不会再独占临界区.

    一些概念(掌握)

    critical resource(临界资源): 系统中的某些资源只允许一个进程使用, 这样的资源称为临界资源.或互斥资源, 或共享变量.

    critical section/region(临界区): 各个进程中对某个临界资源(共享变量)实施操作的代码段.

    2.3 iOS中的买卖票例子(掌握)

    //
    //  ViewController.m
    //  02-线程安全01-购票例子
    //
    //  Created by sixleaves on 15/10/18.
    //  Copyright © 2015年 sixleaves. All rights reserved.
    //
    
    #import "ViewController.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) NSThread * thread01;
    @property (nonatomic, strong) NSThread * thread02;
    @property (nonatomic, strong) NSThread * thread03;
    
    @property (nonatomic, assign) NSInteger ticketCount;
    
    
    @property (nonatomic, strong) dispatch_semaphore_t sema;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(buy:) object:nil];
        self.thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(buy:) object:nil];
        self.thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(buy:) object:nil];
        
        self.ticketCount = 1000;
        
        // 初始化
        self.sema = dispatch_semaphore_create(1);
        
    }
    
    
    - (void)buy:(NSInteger)number {
        
        // 多线程同时操作票数, 造成的数据错乱问题.
        // 解决方式: 1.加锁 2.用信号量
        while (1) {
            
            // P操作
            dispatch_semaphore_wait(self.sema, DISPATCH_TIME_FOREVER);
            
            // 1.拿到票数
            NSUInteger resetTicket = self.ticketCount;
            
            // 2.判断票是否买完
            if (resetTicket > 0) { // 没卖完, 则继续卖.
                
                // 逗号表达式, 从左向右算, 取最后一个的值为表达式值
                NSLog(@"还剩下%ld张 ,买出一张票, 还剩下%ld张.", resetTicket--, resetTicket);
                self.ticketCount = resetTicket;
                
            } else {
                
                NSLog(@"票买完了");
                break;
            }
            
            // V操作
            dispatch_semaphore_signal(self.sema);
        
        }
    }
    
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        if (!([self.thread01 isExecuting] || [self.thread02 isExecuting] || [self.thread03 isExecuting])) {
            
            [self.thread01 start];
            [self.thread02 start];
            [self.thread03 start];
        }
    }
    
    
    @end
    
    
  • 相关阅读:
    base标签使用
    自定义cell的背景图(色)
    如何在iphone 4上使用高分图
    转iphone元素的尺寸
    mac下显示隐藏文件的方法
    转iphone如何调试EXC_BAD_ACCESS
    iphone sleep方法
    uitable view自带的动画效果
    iphone 直接中转到appstore
    uitableview 默认选中第一行
  • 原文地址:https://www.cnblogs.com/objectc/p/4890782.html
Copyright © 2011-2022 走看看