用途

在多线程访问可变变量时,是非线程安全的。可能导致程序崩溃。此时,可以通过使用信号量(semaphore)技术,保证多线程处理某段代码时,后面线程等待前面线程执行,保证了多线程的安全性。使用方法记两个就行了,一个是wait(dispatch_semaphore_wait),一个是signal(dispatch_semaphore_signal)。根据dispatch_semaphore_wait的参数类型提示去创建信号量(dispatch_semaphore_t)即可。

感觉原理跟PV操作如出一辙。

不用semaphore时code:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!"); NSMutableArray *lArrM = [NSMutableArray array];
for (int i = 0; i < 100; ++i) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[lArrM addObject:@(i)];
});
}
}
return 0;
}

运行结果

 SemephoreTest[3665:130800] Hello, World!
SemephoreTest(3665,0x700001daa000) malloc: *** error for object 0x10077b2e0: pointer being freed was not allocated
SemephoreTest(3665,0x700001daa000) malloc: *** set a breakpoint in malloc_error_break to debug
SemephoreTest(3665,0x700001e2d000) malloc: *** error for object 0x102b00340: pointer being freed was not allocated
SemephoreTest(3665,0x700001e2d000) malloc: *** set a breakpoint in malloc_error_break to debug
SemephoreTest[3665:130800] lArrM.count:0
(lldb)

用semaphore时code:

//
// ViewController.m
// SemophoreTest
//
// Created by LongMa on 2019/8/22.
// Copyright © 2019 . All rights reserved.
// #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; NSMutableArray *lArrM = [NSMutableArray array];
dispatch_semaphore_t lSema = dispatch_semaphore_create(1);
for (int i = 0; i < 1000; ++i) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(lSema, DISPATCH_TIME_FOREVER);
[lArrM addObject:@(i)];
NSLog(@"lArrM.count:%zd",lArrM.count);
dispatch_semaphore_signal(lSema);
});
} dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"final delayed lArrM.count:%zd",lArrM.count);
});
} @end

运行结果(用commandlineTool运行代码时,log存在不完整问题):

...
SemophoreTest[9092:877715] lArrM.count:999
SemophoreTest[9092:877730] lArrM.count:1000
SemophoreTest[9092:877696] final delayed lArrM.count:1000

Semaphore回顾的更多相关文章

  1. iOS多线程之GCD、OperationQueue 对比和实践记录

    [toc] 简介      在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的.但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大时钟速度.因此,芯片制 ...

  2. iOS多线程之超实用理论+demo演示(可下载)

    目录 背景简介 GCD.OperationQueue 对比 核心理念 区别 GCD 队列 串行队列(Serial Queues) 并发队列(Concurrent Queues) 串行.并发队列对比图 ...

  3. JUC回顾之-Semaphore底层实现和原理

    1.控制并发线程数的Semaphore Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,保证合理的使用公共资源. 线程可以通过acquire()方法来获取信号量的 ...

  4. Java并发系列[6]----Semaphore源码分析

    Semaphore(信号量)是JUC包中比较常用到的一个类,它是AQS共享模式的一个应用,可以允许多个线程同时对共享资源进行操作,并且可以有效的控制并发数,利用它可以很好的实现流量控制.Semapho ...

  5. Java并发编程笔记之Semaphore信号量源码分析

    JUC 中 Semaphore 的使用与原理分析,Semaphore 也是 Java 中的一个同步器,与 CountDownLatch 和 CycleBarrier 不同在于它内部的计数器是递增的,那 ...

  6. Java回顾之多线程同步

    在这篇文章里,我们关注线程同步的话题.这是比多线程更复杂,稍不留意,我们就会“掉到坑里”,而且和单线程程序不同,多线程的错误是否每次都出现,也是不固定的,这给调试也带来了很大的挑战. 在这篇文章里,我 ...

  7. java架构之路(多线程)JUC并发编程之Semaphore信号量、CountDownLatch、CyclicBarrier栅栏、Executors线程池

    上期回顾: 上次博客我们主要说了我们juc并发包下面的ReetrantLock的一些简单使用和底层的原理,是如何实现公平锁.非公平锁的.内部的双向链表到底是什么意思,prev和next到底是什么,为什 ...

  8. Java并发包5--同步工具CountDownLatch、CyclicBarrier、Semaphore的实现原理解析

    前言: JUC中提供了很多同步工具类,比如CountDownLatch.CyclicBarrier.Semaphore等,都可以作用同步手段来实现多线程之间的同步效果 一.CountDownLatch ...

  9. JUC之Callable接口回顾和JUC辅助类

    Callable接口和JUC辅助类 Callable接口: 回顾: 创建线程的四种方式: 继承Thread 实现runnable接口 实现callable接口 使用线程池 之前的文章:多线程编程1-定 ...

随机推荐

  1. continue和break在while中用法

    continue用法:结束本次循环,不执行continue下面的语句,返回执行下一次循环.注意:当执行完while的循环后,执行else 后的语句 break:结束循环,else下面语句也不执行

  2. 强大的CompletableFuture

    引子 为了让程序更加高效,让CPU最大效率的工作,我们会采用异步编程.首先想到的是开启一个新的线程去做某项工作.再进一步,为了让新线程可以返回一个值,告诉主线程事情做完了,于是乎Future粉墨登场. ...

  3. ITester软件测试小栈,快来点击领取你的能量值!

    日供一卒,功不唐捐,这不是一个非正常更新的ITester软件测试小栈,不定期分享软件测试相关,包括功能.接口.自动化.性能.专项.测试开发,简历指点,面试助攻,群而不党,和而不同,如趋同,且同行.

  4. 【ObjectC—浅copy和深copy】

    一.OC设计copy的目的 为了能够从源对象copy一个新的对象副本,改变新对象(副本)的时候,不会影响到原来的对象. 二.实现copy协议 OC提供了两种copy方法:copy和mutableCop ...

  5. 缓存管理之MemoryCache与Redis的使用

    一..MemoryCache介绍 MemoryCache是.Net Framework 4.0开始提供的内存缓存类,使用该类型可以方便的在程序内部缓存数据并对于数据的有效性进行方便的管理, 它通过在内 ...

  6. 使用AForge录制视频

    使用AForge录制视频,基于Winform开发 (一)首先导入AForge包 需要先导入 using AForge.Video;using AForge.Video.FFMPEG; 两个工具包 (二 ...

  7. python文件的基本操作

    打开文件的三种方式: open(r'E:\学习日记\python\code\文件的简单操作.py') open('E:\\学习日记\\python\\code\\文件的简单操作.py') open(' ...

  8. pat 1041 Be Unique(20 分)

    1041 Be Unique(20 分) Being unique is so important to people on Mars that even their lottery is desig ...

  9. 2018年航空概论课后作业(PS:部分答案不正确, 综合得分:83.6)

    1 [单选题]航空是指载人或不载人的飞行器在地球____的航行活动. • A.高空• B.大气层内• C.宇宙• D.大气层外我的答案:B 得分: 33.3分 2 [多选题]军用飞机可分为____两大 ...

  10. win10添加启动项目

    Win10启动文件夹一般位于C:\ProgramData\Microsoft\Windows\Start Menu(开始菜单)\Programs(程序)\StartUp(启动)目录,我们主要讲希望添加 ...