dispatch_semaphore (信号量)

来源:互联网 发布:网络购物被骗怎么办 编辑:程序博客网 时间:2024/05/16 16:21
#import "ViewController.h"@interface ViewController ()@end@implementation ViewControllerdispatch_semaphore_t semaphore;- (void)viewDidLoad {    [super viewDidLoad];    /*     dispatch_semaphore  (信号量),可以理解为就是当前要访问的资源的数量,比如系统有一个资源可以被利用,有3个线程要访问该资源,为了线程安全,同一时刻只能允许1个线程访问,其他两个线程应当等待资源被释放后再依次访问,此时可以设信号量为1,就可以实现线程同步(让多条线程按顺序执行),即同一时刻只能有一条线程访问同一资源,效果等同于对资源进行加锁     原理: 当信号量的值 <= 0 时,会阻塞当前线程,当信号量大于0时,阻塞取消。     跟信号量相关的函数有三个     1. dispatch_semaphore_create(<#long value#>)        创建信号量,参数为信号量总数     2. dispatch_semaphore_signal(<#dispatch_semaphore_t  _Nonnull dsema#>)        发送信号量,调用该函数信号量 +1,参数为信号量     3. dispatch_semaphore_wait(<#dispatch_semaphore_t  _Nonnull dsema#>, <#dispatch_time_t timeout#>)        等待,调用该函数,信号量 -1;参数为信号量,过期时间(就是等待的时间,当等待的时间超过设定的timeout时间时,即使信号量为0时也会执行后面的代码,类型为dispatch_time_t,不能传进 int 或 float 类型)     dispatch_time_t 类型,它的创建有两个函数     1. dispatch_time(<#dispatch_time_t when#>, <#int64_t delta#>)        第一个参数是从什么时间开始,一般直接传 DISPATCH_TIME_NOW; 表示从现在开始        第二个参数表示具体的时间长度(不能直接传 int 或 float), 可以写成这种形式 (int64_t)3* NSEC_PER_SEC        #define NSEC_PER_SEC 1000000000ull  每秒有1000000000纳秒        #define NSEC_PER_MSEC 1000000ull    每毫秒有1000000纳秒        #define USEC_PER_SEC 1000000ull     每秒有1000000微秒        #define NSEC_PER_USEC 1000ull       每微秒有1000纳秒        注意 delta 的单位是纳秒!         1秒的写作方式可以是 1* NSEC_PER_SEC; 1000* NSEC_PER_MSEC; USEC_PER_SEC* NSEC_PER_USEC     2. dispatch_walltime(<#const struct timespec * _Nullable when#>, <#int64_t delta#>),        第一个参数是一个结构体, 创建的是一个绝对的时间点,比如 2016年10月10日8点30分30秒, 如果你不需要自某一个特定的时刻开始,可以传 NUll,表示自动获取当前时区的当前时间作为开始时刻, 第二参数意义同第一个函数        dispatch_time_t time = dispatch_walltime(NULL, 5* NSEC_PER_SEC);     两个函数的不同       例如: 从现在开始,1小时之后是触发某个事件       使用第一个函数创建的是一个相对的时间,第一个参数开始时间参考的是当前系统的时钟,当 device 进入休眠之后,系统的时钟也会进入休眠状态, 第一个函数同样被挂起; 假如 device 在第一个函数开始执行后10分钟进入了休眠状态,那么这个函数同时也会停止执行,当你再次唤醒 device 之后,该函数同时被唤醒,但是事件的触发就变成了从唤醒 device 的时刻开始,1小时之后       而第二个函数则不同,他创建的是一个绝对的时间点,一旦创建就表示从这个时间点开始,1小时之后触发事件,假如 device 休眠了10分钟,当再次唤醒 device 的时候,计算时间间隔的时间起点还是 开始时就设置的那个时间点, 而不会受到 device 是否进入休眠影响     */    semaphore = dispatch_semaphore_create(1);    dispatch_async(dispatch_get_global_queue(0, 0), ^{        [self firstTask];    });    dispatch_async(dispatch_get_global_queue(0, 0), ^{        [self secondTask];    });    dispatch_async(dispatch_get_global_queue(0, 0), ^{        [self thirdTask];    });}- (void)firstTask{    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);    NSLog(@"first task start");    sleep(1);    NSLog(@"first task end");    dispatch_semaphore_signal(semaphore);}- (void)secondTask{    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)3* NSEC_PER_SEC);    dispatch_semaphore_wait(semaphore, time);    NSLog(@"second task start");    sleep(1);    NSLog(@"second task end");    dispatch_semaphore_signal(semaphore);}- (void)thirdTask{    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);    NSLog(@"third task start");    sleep(1);    NSLog(@"third task end");    dispatch_semaphore_signal(semaphore);}@end//综上:我们可以使用信号量来实现线程同步
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝吃奶粉上火便秘怎么办 20多天的宝宝便秘怎么办 宝宝五十天消化不良不拉屎怎么办 一周七个月宝宝消化不良拉屎怎么办 孩子总是消化不良拉屎不成型怎么办 一岁宝宝长牙慢怎么办 一岁宝宝不喝水怎么办 七个月的宝宝咳嗽怎么办 怀孕七个月感冒了怎么办 苹果汁弄到白色衣服怎么办 宝宝大便干燥拉不出来怎么办 婴儿吃过青菜米粉呕吐怎么办 50天宝宝便秘5天怎么办 8个月婴幼儿便秘怎么办 1个月婴幼儿便秘怎么办 榨汁后的苹果渣怎么办 宝宝6个月后容易生病怎么办 婴儿头型睡偏了怎么办 6个月婴儿不吃奶怎么办 宝宝秋季腹泻反复发烧怎么办 纯甄过期一个月怎么办 四个月宝宝不吃奶瓶怎么办 四个月宝宝不吃奶粉怎么办 婴儿三四天不大便怎么办 婴儿几天不拉大便怎么办 新生儿6天不拉屎怎么办 孩子10天不大便怎么办 宝宝5天没拉屎怎么办 小孩4-5天不大便怎么办 三个月宝宝睡前哭闹厉害怎么办 新生儿抱着睡放下就醒怎么办 宝宝大运动发育迟缓怎么办 八个月宝宝不会爬怎么办 宝宝竖着抱早了怎么办 孕妇吃的水果少怎么办 6个月宝宝厌奶怎么办 5个月宝宝厌奶怎么办 11个月宝宝厌奶怎么办 母乳宝宝不喝奶粉怎么办 换奶粉不拉大便怎么办 宝宝和妈妈不亲怎么办