信号量

线程之Semaphore之事例

删除回忆录丶 提交于 2020-04-05 15:59:36
概述 为了提高接口的响应速度,可以使用 ThreadPoolExecutor + Runnable 或者 ThreadPoolExecutor 并发调用 技术来并行执行task。但是ThreadPoolExecutor有个特点,就是当core线程不足以应付请求的时候,会将task加入到队列中。一旦使用队列,那么就可能出现队列爆掉或者队列导致的内存溢出问题。 为了尽快提供接口响应速度,但是又不想使用队列特性的话。可以使用信号量来做到。 Semaphore信号量管理着一组许可,在执行操作时需要首先获得许可,并在使用后释放许可。如果已经没有许可了, acquire方法将一直阻塞,直到有许可。 信号量简单例子 ThreadPoolExecutor中使用信号量 在ThreadPoolExecutor中,我们在定义core线程参数的时候,比如定义为10个,那么使用信号量的时候,初始化参数也设置为10. Semaphore<Integer> sem= new Semaphore<>(10); ThreadPoolExecutor中,如果不想用到队列, 就必须保证线程池中始终只有core线程在工作 。那么当请求太多,core线程处理不过来的时候,用信号量进行阻塞, 保证只有当core线程的某些线程执行完后,阻塞才解开。 这里使用JAVA并发编程一书中的例子来说明信号量的基本用法。 public

java多线程

旧城冷巷雨未停 提交于 2020-04-04 06:16:05
1、进程与线程 我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程(Thread)。 线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。 当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。 同步这个词是从英文synchronize(使同时发生)翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用,咱们也就只好这么将就。 线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作 。 因此,关于线程同步,需要牢牢记住的第一点是: 线程同步就是线程排队 。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。 关于线程同步,需要牢牢记住的第二点是 “共享” 这两个字。 只有共享资源的读写访问才需要同步 。如果不是共享资源,那么就根本没有同步的必要。 关于线程同步,需要牢牢记住的第三点是,只有“ 变量 ”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。

iOS多线程——GCD篇

左心房为你撑大大i 提交于 2020-04-03 05:25:54
什么是GCD GCD是苹果对多线程编程做的一套新的抽象基于C语言层的API,结合Block简化了多线程的操作,使得我们对线程操作能够更加的安全高效。 在GCD出现之前Cocoa框架提供了NSObject类的 performSelectorInBackground:withObject performSelectorOnMainThread 方法来简化多线程编程技术。 GCD可以解决以下多线程编程中经常出现的问题: 1.数据竞争(比如同时更新一个内存地址) 2.死锁(互相等待) 3.太多线程导致消耗大量内存 在iOS中,如果把需要消耗大量时间的操作放在主线程上面,会妨碍主线程中被称为RunLoop的主循环的执行,从而导致不能更新用户界面、应用程序的画面长时间停滞等问题。 Dispatch Queue Dispatch Queue是GCD中对于任务的抽象队列(FIFO)执行处理。 queue分为两种, SERIAL_DISPATCH_QUEUE           等待现在执行中处理结束 CONCURRENT_DISPATCH_QUEUE       不等待现在执行中处理结束 换句话说也就是 SERIAL_DISPATCH_QUEUE 是串行,CONCURRENT_DISPATCH_QUEUE是并行。 具体到线程上,就是SERIAL_DISPATCH

iOS-关于GCD信号量那些事儿

随声附和 提交于 2020-03-30 19:55:48
随便说说 其实GCD大家都有接触过,也不在解释GCD是什么,为什么突然想说信号量问题,最近这几次面试,当我问到面试者怎么处理多个请求完成后的一系列操作时,有的说造一个临时变量的做追加,其实这样可以,也算是信号量的基本逻辑,有的说用线程做延时操作,怎么延时,怎么操作说的不清楚,有少部分会提到GCD信号量,但是可能说不出来怎么操作,通过信号量的增加与递减,进行网络的并发请求,最后再做网络请求完成后的最终处理;其实实际上大家在做的时候,在网上一搜,基本都能找到; GCD信号量的应用场景,一般是控制最大并发量,控制资源的同步访问,如数据访问,网络同步加载等 简单聊聊 ///创建 dispatch_semaphore_create() ///增加 dispatch_semaphore_signal() ///减去 dispatch_semaphore_wait() 下面用简单的栗子模拟多个网络请求,再进行最终的操作 //创建信号量 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //创建队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); //创建线程组 dispatch_group_t group = dispatch_group_create(

第十三周学习报告

拟墨画扇 提交于 2020-03-28 15:26:37
第十三周(11.30-12.06): 一、学习目标 1. 掌握三种并发的方式:进程、线程、I/O多路复用 2. 掌握线程控制及相关系统调用 3. 掌握线程同步互斥及相关系统调用 二、学习资源 1. 教材:第十一章《网络编程》简单过一下 2. 教材:第十二章《并发编程》 并发编程 如果逻辑控制流在时间上重叠,那么他们就是并发的,这种常见的现象叫做并发。 并发不限制于内核: 访问慢速I/O 设备 与人交互 通过推迟工作以降低延迟 服务多个网络客户端 在多核机器上进行并发计算 进程 I/O多路复用 线程 12.1基于进程的并发编程 第一步:服务器接受客户端的连接请求 第二步:服务器派生一个子进程为这个客服端服务 第三步:服务器接受另一个连接请求 第四步:服务器派生另一个子进程为新的客户端服务 12.1.2关于进程的优劣 模型:共享文件表,但是不共享用户地址空间 独立的地址空间使得进程共享状态信息变得更加困难 基于I/O多路复用的并发编程 对于两个事件: 网络客户端发起的连接请求 用户在键盘上输入命令行 针对不知道等待哪个事件,一个解决办法就是I/O多路复用技术。 基本思路就是使用select函数,要求内核挂起进程,只有在一个或者多个I/O事件发生后,才将控制返回给应用程序,就像P651事例一样: 当集合{0,4}中任意描述符准备好读时返回。 当集合{1,2,7}中任意描述符准备好写时返回

spin_lock & mutex_lock的区别?

≯℡__Kan透↙ 提交于 2020-03-28 05:07:59
http://blog.csdn.net/sunnytina/article/details/7615520 为什么需要内核锁? 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理 有哪些内核锁机制? (1)原子操作 atomic_t数据类型,atomic_inc(atomic_t *v)将v加1 原子操作比普通操作效率要低,因此必要时才使用,且不能与普通操作混合使用 如果是单核处理器,则原子操作与普通操作相同 (2)自旋锁 spinlock_t数据类型,spin_lock(&lock)和spin_unlock(&lock)是加锁和解锁 等待解锁的进程将反复检查锁是否释放,而不会进入睡眠状态(忙等待),所以常用于短期保护某段代码 同时,持有自旋锁的进程也不允许睡眠,不然会造成死锁——因为睡眠可能造成持有锁的进程被重新调度,而再次申请自己已持有的锁 如果是单核处理器,则自旋锁定义为空操作,因为简单的关闭中断即可实现互斥 (3)信号量与互斥量 struct semaphore数据类型,down(struct semaphore * sem)和up(struct semaphore * sem)是占用和释放 struct mutex数据类型,mutex_lock(struct mutex *lock)和mutex

线程同步(互斥锁与信号量的作用与区别)

感情迁移 提交于 2020-03-28 03:59:40
“信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的” 也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。 两者之间的区别: 作用域 信号量: 进程间或线程间(linux仅线程间的无名信号量pthread semaphore) 互斥锁: 线程间 上锁时 信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一 互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源 以下是信号灯(量

C#信号量

点点圈 提交于 2020-03-25 14:59:37
转载于: https://www.cnblogs.com/doublejun/p/7520347.html Semaphore是System.Threading下的类,限制可同时访问某一资源或资源池的线程数。 常用构造方法 https://msdn.microsoft.com/zh-cn/library/e1hct27h(v=vs.110).aspx public Semaphore( int initialCount, int maximumCount ) 参数 initialCount Type: System.Int32 可以同时授予的信号量的初始请求数。 maximumCount Type: System.Int32 可以同时授予的信号量的最大请求数。 示例代码 class Program { static Semaphore sema = new Semaphore(1,1); static void Main(string[] args) { for (int i = 0; i < 3; i++) { var thread = new Thread(Test) { Name = $"Thread{ i }" }; thread.Start(); } Console.ReadKey(); } static void Test() { sema.WaitOne(); for

运用PV心法解决多线程问题

强颜欢笑 提交于 2020-03-23 11:00:32
3 月,跳不动了?>>> 总结写在前面: 1.注意设置的信号量的初值。 2.不管如何变,只要牢牢的抓住同步和互斥来分析问题。 3. 先靠滤同步情况即所有“等待”情况。有几个 “ 等待”信号量类型就有几个。 4. 接下来 靠滤 要互斥处理的资源。 先讲讲 PV 操作的起源和用法。 1962 ,荷兰学者 Dijksrta 在参与 X8 计算机的开发中设计并实现了具有多道程序运行能力的操作系统 ——THE Multiprogramming System 。为了解决这个操作系统中进程(线程)的同步与互斥问题,他巧妙地利用火车运行控制系统中的“信号灯”( semaphore ,或叫“信号量”)概念加以解决。信号量的值大于 0 时,表示当前可用资源的数量;当它的值小于 0 时,其绝对值表示等待使用该资源的进程个数。注意,这个信号量的值仅能由 PV 操作来改变。 PV 操作由 P 操作原语和 V 操作原语组成(原语也叫原子操作 Atomic Operation ,是不可中断的过程),对信号量(注意不要和Windows中的 信号量机制 相混淆)进行操作,具体定义如下: P(S) : ①将信号量 S 的值减 1 ,即 S=S-1 ; ②如果 S>=0 ,则该进程继续执行;否则该进程置为等待状态。 V(S) : ①将信号量 S 的值加 1 ,即 S=S+1 ; ②该进程继续执行

信号量 - semaphore

房东的猫 提交于 2020-03-22 17:12:27
一. POSIX - 信号量 #include <semaphore.h> sem_t sem; ///< 信号量 信号量,分为有名信号量 和无名信号量。 有名信号量由sem_open/sem_close/sem_unlink创建/关闭/销毁,用于进程间通信。 无名信号量由sem_init/sem_destroy创建/销毁,用于线程间通信。 1. 信号量初始化 /*********************************************************** * @param[sem] 非命名信号量,只能被sem_destroy()销毁, * @param[pshared] 非0表示进程间通信信号量,但是Linux系统暂未实现这一功能(实现方式为共享内存),0表示线程间通信信号量。 * @param[value] 信号量初始化值 * @return 成功返回0,失败返回-1及设置错误码errno *//********************************************************/ int sem_init(sem_t * sem, int pshared, unsigned vlaue); /*********************************************************** *