文档章节

利用操作队列和信号量来实现操作同步

vimfung
 vimfung
发布于 2013/06/26 22:16
字数 785
阅读 871
收藏 17

     最近在开发iOS过程中遇到一个问题:某一些操作需要在一个初始化操作后才允许执行。但是这些操作的执行时刻有可能比初始化操作来得要快。那么,如果不等待初始化操作后再执行的话,这些操作就等于是丢失了。

     针对这个问题,我想到了两种解决方案:第一就是执行这些操作之前先判断是否已经初始化,如果尚未初始化则使用一个数组队列把操作参数及调用的方法存储起来,等待初始化完成后再检测数组队列中的保存的操作进行调用并清空队列。但这种方式有个问题就是操作中传递的参数以及调用方法引用都需要自己来维护,这无疑是给自己带来了一定的工作量以及风险,稍有不慎就有可能会导致内存泄露。

     因此第二中解决方法就是利用串行队列结合信号量的方式来控制操作的执行。此方案的思路是,先创建一条串行队列,此队列用于执行所有的操作。但是最先入队的是一个等待信号的操作。而这个信号的初始值是0,直到初始化操作完成后才会发送一个信号来通知此操作。因此,在尚未初始化完成的时候此队列是一直处于阻塞状态的。所以到有操作进入队列时都会立刻执行,而是需要等到初始化信号过来后才开始执行。

     为了验证这一想法,我新建了一个应用工程,在ViewController中定义了操作队列_quque和信号量_sema,如下:

@interface ViewController : UIViewController
{
@private
    dispatch_queue_t _queue;
    dispatch_semaphore_t _sema;
}

@end

初始化时创建操作队列

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
    {
        _queue = dispatch_queue_create("cn.vimfung.demo", DISPATCH_QUEUE_SERIAL);
    }
    
    return self;
}

     在ViewController中定义了三个按钮,分别为DoSomething、Signal、Wait。其中DoSomething为执行的操作。Signal为通知阻塞队列可以执行操作了。Wait为阻塞当前队列。

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn setTitle:@"DoSomething" forState:UIControlStateNormal];
    [btn sizeToFit];
    [btn addTarget:self action:@selector(doSomethingHandler:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn1 setTitle:@"Signal" forState:UIControlStateNormal];
    [btn1 sizeToFit];
    [btn1 addTarget:self action:@selector(signalHanlder:) forControlEvents:UIControlEventTouchUpInside];
    btn1.frame = CGRectMake(0.0, 50.0, btn1.frame.size.width, btn1.frame.size.height);
    [self.view addSubview:btn1];
    
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn2 setTitle:@"Wait" forState:UIControlStateNormal];
    [btn2 sizeToFit];
    [btn2 addTarget:self action:@selector(waitHanlder:) forControlEvents:UIControlEventTouchUpInside];
    btn2.frame = CGRectMake(0.0, 100.0, btn2.frame.size.width, btn2.frame.size.height);
    [self.view addSubview:btn2];
}

- (void)doSomethingHandler:(id)sender
{
    dispatch_async(_queue, ^{
        NSLog(@"do something");
    });
}

- (void)signalHanlder:(id)sender
{
    dispatch_semaphore_signal(_sema);
}

- (void)waitHanlder:(id)sender
{
    if (_sema)
    {
        dispatch_release(_sema);
    }
    _sema = dispatch_semaphore_create(0);
    dispatch_async(_queue, ^{
        dispatch_semaphore_wait(_sema, DISPATCH_TIME_FOREVER);
    });
}

      运行后,先点击Wait让队列阻塞、然后这时无论怎么点击DoSomething都是不会有log信息显示,直到点击Signal后,之前点击的DoSomething将会一一打印出来信息。

      可见这种解决方案是可行的,并且可以更加容易操作。

© 著作权归作者所有

vimfung

vimfung

粉丝 60
博文 59
码字总数 85338
作品 4
广州
技术主管
私信 提问
Linux进程间通信(六)---信号量通信之semget()、semctl()、semop()及其基础实验

这个信号量理解起来是有点不容易啊,我看书看了好几遍才知道怎么回事。在讲这一节信号量之前,我还是想先说几个小知识点,这也是我在学习完后最终理解的“精华”,哈哈! 信号量是干啥的? ...

长平狐
2013/06/17
5.2K
0
操作系统清华大学版笔记(十) 信号量、管程、条件互斥、经典同步问题(读者写者、哲学家问题)

10-1 信号量 Semaphore 一个整型int(sem),可进行两个原子操作 P() sem–,如果sem<0,等待,否则继续,类似lock_acquire V() sem++,如果sem<=0,说明当前有等着的,唤醒挂在信号量上的进...

xiaoshuaisdl
2018/04/10
0
0
PV操作和信号量机制实现进程同步(对多个临界资源的互斥访问)

进程同步是我们在多线程中讨论最多的一个话题,在大多数的开发语言中,他们都有自己实现进程同步的方法或者实现。但归根结底他们实现的方式都是基于操作系统的进程同步的方式。今天我们就一起...

长平狐
2012/11/12
676
0
Linux进程间通信---信号量通信之semget()、semctl()、semop()

这个信号量理解起来是有点不容易啊,我看书看了好几遍才知道怎么回事。在讲这一节信号量之前,我还是想先说几个小知识点,这也是我在学习完后最终理解的“精华”,哈哈!   信号量是干啥的...

B_ice
2016/07/23
19
0
操作系统之——进程管理:同步进程和进程互斥

操作系统进程管理-同步和互斥 在看了操作系统关于进程管理中的同步互斥机制章节之后,甚是困惑,今天通过视频、网上博客资料学习之后,整理一下相关知识点。 进程管理 一、进程互斥 由于进程...

善水输出端
2018/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

高并发场景下的缓存有哪些常见的问题?

一、缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。 这就比较依赖缓存的过期和更新...

别打我会飞
15分钟前
1
0
List list = new ArrayList()为何父类引用指向子类对象(多态)

态:要有继承,方法的重写,父类引用指向子类对象 疑问一:父类引用指向子类对象 与指向父类对象 Animal cat = new Cat(); //向上转型。 父类引用指向子类对象,该引用不能再访问子类新增加的...

architect刘源源
15分钟前
0
0
分而治之-快速排序

快速排序的思想: 快速排序首先在数组中确定1个枢纽项(比如数组中的第一个元素),将大于该枢纽项的元素放到右侧,小于该枢纽项的元素放到左侧,这样枢纽项将数组划分成两部分。接着继续对划...

万山红遍
今天
4
0
Qt编写自定义控件9-导航按钮控件

前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有的CSS2属...

飞扬青云
今天
3
0
Python开发工具:pyJasper

原文:https://www.oschina.net/p/pyjasper 前言 pyJasper是 JasperReports 网络服务器的 Python 客户端。 pyJasper 是一组 Python 基础工具,可以用来处理 JasperReports 报表 。因为 Jasper...

A_裙232550246
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部