dispatch_semaphore使用方法

第一、引入

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSMutableArray *arr=[NSMutableArray new];

for (int i=0; i<100; i++) {

dispatch_async(queue, ^{[arr addObject:[NSNumber numberWithInt:i]];

NSLog(@"the thread is %d",i);

NSLog(@"%@",arr);

});

}

多个线程并发修改数组arr,线程不安全,应该增加安全机制,官方文档:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html

第二、GCD实现同步的信号量

dispatch_semaphore是GCD的信号量机制,支持三个基本的操作:

dispatch_semaphore_create   创建一个semaphore,可以指定信号量的值

  dispatch_semaphore_signal   发送一个信号,信号量加1

  dispatch_semaphore_wait    等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1

实例:

int data = 3;

__block int mainData = 0;

__block dispatch_semaphore_t sem = dispatch_semaphore_create(0);

dispatch_queue_t queue = dispatch_queue_create("richard", DISPATCH_QUEUE_PRIORITY_DEFAULT);

dispatch_async(queue, ^(void) {

int sum = 0;

for(int i = 0; i < 5; i++)

{

sum += data;

NSLog(@" Sum: %d", sum);

}

dispatch_semaphore_signal(sem);

});

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

for(int j=0;j<5;j++)

{

mainData++;

NSLog(@">> Main Data: %d",mainData);

}

执行结果:

Sum: 3

Sum: 6

Sum: 9

Sum: 12

Sum: 15

Main Data: 1

Main Data: 2

Main Data: 3

Main Data: 4

Main Data: 5

通过信号量机制保证mainData是在sum后执行

第三、用信号量机制实现同步的实例

针对引言提出的多线程不安全的问题,我们利用信号量机制可以实现一个安全的sample

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);

dispatch_semaphore_t sem=dispatch_semaphore_create(1);

NSMutableArray *arr=[NSMutableArray
new];

for (int i=0; i<20; i++) {

dispatch_async(queue, ^{

dispatch_semaphore_wait(sem,
DISPATCH_TIME_FOREVER);

[arr addObject:[NSNumber
numberWithInt:i]];

NSLog(@"%@",arr);

dispatch_semaphore_signal(sem);

});

}

结果:

2015-02-02 15:15:36.153 testApp[3433:84946] (

    0

)

2015-02-02 15:15:36.154 testApp[3433:84946] (

    0,

    6

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8,

    10

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11,

    12

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11,

    12,

    14

)

2015-02-02 15:15:36.155 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15

)

2015-02-02 15:15:36.156 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17

)

2015-02-02 15:15:36.156 testApp[3433:84958] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18

)

2015-02-02 15:15:36.156 testApp[3433:84948] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3

)

2015-02-02 15:15:36.156 testApp[3433:84952] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4

)

2015-02-02 15:15:36.177 testApp[3433:84956] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13

)

2015-02-02 15:15:36.178 testApp[3433:84953] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5

)

2015-02-02 15:15:36.178 testApp[3433:84954] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7

)

2015-02-02 15:15:36.179 testApp[3433:84957] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7,

    16

)

2015-02-02 15:15:36.179 testApp[3433:84947] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7,

    16,

    1

)

2015-02-02 15:15:36.179 testApp[3433:84949] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7,

    16,

    1,

    2

)

2015-02-02 15:15:36.180 testApp[3433:84946] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7,

    16,

    1,

    2,

    19

)

2015-02-02 15:15:36.182 testApp[3433:84955] (

    0,

    6,

    8,

    10,

    11,

    12,

    14,

    15,

    17,

    18,

    3,

    4,

    13,

    5,

    7,

    16,

    1,

    2,

    19,

    9

)

时间: 2024-10-30 02:21:51

dispatch_semaphore使用方法的相关文章

Unity 崩溃问题解决方法——之一

友情提示:工作随记,不喜勿喷 注意:文艺青年可以略过,暴力青年欢迎采纳 Library文件夹 Unity每次编译都会生成这个东西,不用担心丢失的问题.所以,干掉他! 选中 + Delete   或者  选中 + Shift  + Delete 网上看了很多方法,就觉得这个简单,粗暴,是我喜欢的类型. 优点:上面说了 缺点:如果工程过大,重新编译时间会比较长.(但是对于查Log日志来说,相对快点)

Java TM 已被阻止,因为它已过时需要更新的解决方法

公司的堡垒机需要通过浏览器登陆,且该堡垒机的网站需要Java的支持,最近通过浏览器登陆之后总是提示"java TM 已被阻止,因为它已过时需要更新的解决方法"导致登陆之后不能操作, 但是操作系统中确实已经安装了比较新的JDK,安装的JDK版本是jdk-7u67-windows-i586,因为太烦人,所以决定搞清楚报错的原因,一劳永逸,彻底解决这个问题 准备工作:安装JDK,安装版本jdk-7u67-windows-i586.exe,因为机器的Eclipse还依赖64位的JDK,所以另安

win7 64位系统 PB连接oracle数据库出现“oracle library oci.dll could not be loaded”问题的解决方法

今天与大家分享一个自己的学习笔记,希望能给遇到同样问题的人带来帮助. 不知道大家在win7 64位系统下用 PB连接oracle数据库时,是否遇到过“oracle library oci.dll could not be loaded”问题. 今天,在win7 64位系统下用 PB连接oracle数据库时,一直出现上述错误,在百度上找了很久,都没有找到一个完整的解决方案,咨询了很多人,(他们都说是我的PB和oracle没装好,但我装的时候没出现任何问题,一切都很顺利,而且PB和oracle都能正

C#与数据库访问技术总结(八)之ExecuteNonQuery方法

ExecuteNonQuery方法 ExecuteNonQuery方法主要用来更新数据. 通常使用它来执行Update.Insert和Delete语句. 该方法返回值意义如下: 对于Update.Insert和Delete语句,返回值为该命令所影响的行数. 对于所有其他类型的语句,返回值为-1. Command对象通过ExecuteNonQuery方法更新数据库的过程非常简单,需要进行的步骤如下: (1)创建数据库连接. (2)创建Command对象,并指定一个SQL Insert.Update

android开发之onCreate( )方法详解

onCreate( )方法是android应用程序中最常见的方法之一,那么,我们在使用onCreate()方法的时候应该注意哪些问题呢? 先看看Google Android Developers官网上的解释: onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually call setContentView(int) with a layout resource d

MAC平台下Xcode配置使用OpenCV的具体方法 (2016最新)

1.序言: 1.1 背景 本人小白一枚,不过因为最近在从事机器视觉方面的工作,所以接触到OpenCV. 因为工作需求,本人要在MAC端使用OpenCV实现一些视觉功能,配置环境成了最大的阻碍,网上查了很多相关资料和博客,都因为版本环境问题屡试屡败,不过经历重重尝试,笔者最终还是配置成功并运行了自己的源码.当然成功的关键还是因为笔者站在了巨人的肩膀上,借鉴了很多网上的教程,为了不误导大家配置的过程,参考文章的地址统一放在文章里,望各位大大看见之后能够理解,废话不说进入正题. 1.2 环境说明 如果

正则化方法:L1和L2 regularization、数据集扩增、dropout

本文是<Neural networks and deep learning>概览 中第三章的一部分,讲机器学习/深度学习算法中常用的正则化方法.(本文会不断补充) 正则化方法:防止过拟合,提高泛化能力 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合).其直观的表现如下图所示,随着训练过程,网络在training data上的error渐渐减小,但是在验证集上的error却反而渐渐增大--因为训练出来的网络过拟合了训练集,对训练集外的数据却不work

mac上 go-delve 安装出现The specified item could not be found in the keychain 解决方法

安装go语言的编译环境,在安装到 delve时候出现如下错误: If reporting this issue please do so at (not Homebrew/brew or Homebrew/core): https://github.com/go-delve/homebrew-delve/issues These open issues may also help: Upgrade to delve fails https://github.com/go-delve/homebr

初识运维3--在虚拟机中安装Linux发行版系统(CentOS)的方法

在讲Linux系统发行版本的安装过程之前,先大略说明一下虚拟化. 虚拟化:将底层硬件资源抽象为用户更容易读懂和使用的逻辑抽象层的技术. 最早由IBM提出,现使用率较高的虚拟化软件平台有三类:VMware workstation.VirtualBOX.HyperV.在这里使用VMware workstation作为例子讲解说明安装过程. 虚拟化网络: 桥接模式:让物理机和虚拟机利用物理网络接口完成通信.虚拟机可以访问互联网. 仅主机模式:让虚拟机和物理机利用被虚拟出来的VMnet1网络接口完成通信