信号量

CountDownLatch,CyclicBarrier,Semaphore

送分小仙女□ 提交于 2020-03-21 15:25:06
CountDownLatch是倒数,doneSignal = new CountDownLatch(LATCH_SIZE);赋初值后,在主线程中等待doneSignal.await();其它线程中,每完成一个就减一doneSignal.countDown();减到0时主线程继续。 CyclicBarrier是正数,cb = new CyclicBarrier(SIZE);主线程中开启各子线程,子线程调用cb.await()进行等待;cb计数count会加一,等于SIZE时会继续所有等待线程。 Semaphore是信号灯,Semaphore sem = new Semaphore(SEM_MAX);主线程中开启各子线程,子线程调用sem.acquire(count);每调用一次,sem计数会减相应数值,减为0时其它线程再调用acquire时会阻塞,线程结束后记得要sem.release(count); CountDownLatch和Semaphore用的是共享锁,而CyclicBarrier是独占锁。 CountDownLatch只能赋值一次,而CyclicBarrier可赋值多次。 概要 前面对" 独占锁 "和" 共享锁 "有了个大致的了解;本章,我们对CountDownLatch进行学习。 和ReadWriteLock.ReadLock一样

计算机操作系统基础知识-2

旧街凉风 提交于 2020-03-21 01:22:16
Shell Shell是操作系统与用户交互的界面。表现为通过控制台执行用户命令。本身不执行命令,仅仅是组织和管理命令。 脚本:类似程序的方式执行一系列的逻辑顺序的命令序列完成复杂的功能和人机交互。保存在文件中,是shell命令的集合。 系统调用 定义:操作系统内核为应用程序提供的服务/函数 特点: 一般涉及核心操作和硬件资源 运行于核态 函数具有唯一ID 产生中断,且为自愿中断 进程管理 定义:是程序在某个数据集合上的一次运行活动。程序的一次运行即为一个进程。 特性: 动态性 并发性 异步性 独立性 分类: 按使用资源权限 系统进程:系统内核相关进程 用户进程:运行于用户态的进程 按对CPU依赖性 偏CPU进程:计算型 偏I/O进程: 进程状态 就绪态:获得了除CPU之外所有资源,通常有多个进程处于就绪态,有一个就绪队列。 运行态:获得CPU,正在运行 等待态: 进程控制块 进程由程序、数据、进程控制块组成。 进程控制块是描述和管理进程的一种数据结构,包括以下内容: 进程描述信息 控制和调度信息 资源信息 现场信息 进程互斥和同步 同步:进程通过协作共同完成同一任务而造成的直接制约关系,如生产者-消费者模式 互斥:进程间竞争系统资源而造成的间接制约关系,同一时间内只有一个进程可以访问系统资源。 临界资源和临界区 临界资源:同一时间只能有一个进程访问的资源 临界区

2019年9月25日星期三(STM32 ucos3)

99封情书 提交于 2020-03-17 17:12:09
一.UCOS 1.概念 uc/OS-III(Micro C OS Thee),微型C语言编写的操作系统第三版。是一个可升级,可固化,多任务基于优先级的可抢占式实时内核。 ucos的任务个数不限制,实现了操作系统所需求的大部分功能,资源管理,同步,任务之间的通信。除了这些基本的功能以外,还提供一些其他的实时性内核找不到的特色功能,比如完备的运行时间测量,也可以直接发送信号/消息到某个任务,任务也可以同时等待多个内核对象 由于ucos体积微小,功能强悍,可移植性强,在微控制器领域应用广泛 ucos要收费,有时候我们会选择免费的系统,比如freeRTOS....,以及一些其他和物联网结合操作系统(华为liteOS 阿里巴巴.. 腾讯..) 2.ucos移植 (1)源代码结构 EvalBoards ------------ 工程文件 uc-CPU -------------- CPU相关代码 uc-LIB -------------- 和硬件/编译器 无关的库函数(字符串 数学 内存) uCOS-III ----------- ucos操作系统相关代码 (2)将源码拷贝到工程,修改源码(详情见手册) (3)特性 3.ucos的任务调度和任务 合作式调度 -------- 多个任务按照指定时间和顺序依次运行,下一个任务等待上一个任务时间用完再开始运行 抢占式调度 --------

操作系统7-信号量与管程

旧街凉风 提交于 2020-03-17 15:31:59
回顾一下 : 并发问题:多线程并发导致资源竞争 同步概念: ---------1. 协调多线程对 共享数据 的访问 ---------2.任何时刻只能由一个线程执行临界区代码 确保同步正确的方法 ---------底层硬件支持 ---------高层次的编程抽象( 锁 ) 信号量是锁机制在同一层上的高层抽象编程方法 一、 信号量semaphore 信号量是操作系统提供的一种 协调共享资源访问 的方法, 用信号量表示系统资源的数量 信号是一种抽象数据类型,由一个整型(sem)变量和两个原子操作组成: 1)P():sem减1,如sem<0,表示申请资源(减1)后没有资源了,需要等待 2)V():sem加1,如sem<=0,即一个资源用完(加1)但还是小于0表示还有资源在等待,那么就唤醒一个等待进程 信号量是被保护的整数变量。初始化完成后就只能通过P()和V()操作来修改,并且由操作系统来保证PV操作时原子操作 P可能由于没有资源而进入阻塞状态,但是V操作不会被阻塞 假定信号量实现的同步是公平的,线程不会被阻塞在P()操作中,并且信号量等待按先进先出 信号量的实现 class Semophore { int sem ; WaitQueue q ; } Semophore :: P ( ) { sem -- ; //申请一个资源 if ( sem < 0 ) //资源不够,要等待 {

操作系统——进程

雨燕双飞 提交于 2020-03-17 03:12:59
什么是作业、进程、线程、管程? 作业:用户在一次解题或一个事务处理过程中要求计算机系统所做工作的集合。它包括用户程序、所需要的数据及控制命令等。作业由一系列有序的步骤组成。 进程:一个程序在一个数据集合上的一次运行过程。所以一个程序在不同数据集合上运行,乃至一个程序在同样数据及上上的多次运行都是不同的进程。 线程:线程是一个进程的实体,是被系统独立调度和执行的基本单位。 管程:实际上是定义一个数据结构在该数据结构上的能为并发进程所执行的一组操作,这组操作能同步进程和改变管程中的数据。 进程间通信是如何实现的? 进程间通信的方式有信号、信号量、消息队列、共享内存。 进程通信 是指不同进程之间的一些“接触”。 信号和信号量是不同的 ,他们都可以用来实现同步和互斥,但信号是使用信号处理器来进行的,信号量是使用P\V操作来实现的。消息队列是比较高级的一种进程间通信方法,他真的可以在进程间传送message,连传送一个“i seek you”都可以。 一个消息队列是可以被多个进程所共享;如果一个进程的消息太多,一个消息队列放不下,也可以用多于一个的消息队列(管理会比较复杂)。共享消息队列的进程所发送的消息除了message本身外还有一个标志,这个标志可以指明该消息将由哪个进程或哪类进程所接受。 每一个共享消息队列的进程针对这个队列也有自己的标志,可以用来表明自己的身份。

windows多线程同步--临界区

浪子不回头ぞ 提交于 2020-03-16 14:33:30
推荐参考博客: 秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念 ,一般操作系统书上面都有。 适用范围:它只能同步一个进程中的线程,不能跨进程同步。一般用它来做单个进程内的代码快同步,效率比较高 windows中与临界区有关的结构是 CRITICAL_SECTION,关于该结构体的内部结构可参考 here 使用时,主线程中要先初始化临界区,最后要删除临界区,具体使用见下面代码: 本文地址 从一个例子来说明:假设有三个线程都需要使用打印机,我们可以把打印的代码放到临界区,这样就可以保证每次只有一个线程在使用打印机。 #include<string> #include<iostream> #include<process.h> #include<windows.h> using namespace std; //定义一个临界区 CRITICAL_SECTION g_cs; //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall unsigned __stdcall threadFun(void *param) { EnterCriticalSection(&g_cs);//进入临界区,如果有其他线程则等待 cout<<*(string *)(param)<<endl; LeaveCriticalSection(&g_cs);//退出临界区,其他线程可以进来了

进程的经典同步问题

时间秒杀一切 提交于 2020-03-12 19:07:17
P、V操作描述简单同步 设同步信号量empty,含义为缓冲单元为空,初值为1 设同步信号量full,含义为缓冲单元为满,初值为0 输入进程: 申请空缓冲单元; P(empty); 输入数据到缓冲单元; 输入数据到缓冲单元; 释放满缓冲单元; V(full) 计算进程 申请满缓冲单元; P(full) 从缓冲单元取数据; 从缓冲单元取数据 释放空缓冲单元; V(empty); 同步:每一个同步信号量P、V操作成对出现在不同的进程代码中 经典同步问题 生产者消费者问题 P、V操作描述进程同步互斥问题步骤: 分析进程同步互斥关系; 设响应同步互斥信号量; 用P、V操作描述进程活动。 描述了一组生产者向一组消费者提供产品(数据),它们共享一个有界缓冲区,生产者向其中投放产品,消费者从中取出产品消费,生产者和消费者互斥使用整个缓冲池。 分析: 只要缓冲区未满,生产者就可把产品送入缓冲区,只要缓冲区未空,消费者便可从缓冲区取走产品并消耗它。 仅当缓冲区满时,生产者被阻塞,类似地,缓冲区空时,消费者被阻塞。 设置两个同步信号量:empty:表示空缓冲单元的数目,初值为缓冲区的大小n; full:表示满缓冲单元(即产品)的数目,初值为0; 设置互斥信号量mutex:表示整个缓冲池,初值为1。 生产者进程Pi(i=1,2,……,m) 总结 两个P操作不可用颠倒,如生产者进程中如颠倒

信号量-PV操作题

北城以北 提交于 2020-03-11 22:59:07
PV操作 信号量semaphore PV操作 生产者消费者问题 读者写作问题 哲学家就餐问题 理发师睡觉问题 信号量semaphore 表示资源个数的整型量 >0 表示当前资源的个数 <0 其 绝对值 表示系统中因请求该类资源而造成的 阻塞进程 个数 PV操作 两条原语(一种特殊的操作 不能被系统中断 ) P(S)= -1分配一个可用资源 V(S)= +1释放一个资源 生产者消费者问题 共享一个缓冲区,生产者投放/消费者获取 semaphore mutex=1; //控制生产者消费者之一进入缓冲区 semaphore full=0; //缓冲区中满的个数 semaphore empty=n; //缓冲区中空的个数 main(){ cobegin producer(); consumer(); coend } producer(){ while(true){ 生产; P(empty); P(mutex); 将一个产品放入缓冲区; V(mutex); V(full); } } consumer(){ while(true){ P(full); P(mutex); 取一个产品出缓冲区; V(mutex); V(empty); 消费; } } 生产和消费操作中的P(占用)操作不能交换顺序,否则可能产生死锁 读者写作问题 多个读者可以同时访问数据集

什么是信号量?

折月煮酒 提交于 2020-03-11 19:51:12
信号量是一种编程概念,经常用于解决多线程问题。 我对社区的问题: 什么是信号量,如何使用? #1楼 因此,想象每个人都在尝试去洗手间,而洗手间只有一定数量的钥匙。 现在,如果没有足够的键,该人需要等待。 因此,可以将信号量视为代表可用于浴室(系统资源)的那些键集,以供不同进程(浴室行进者)请求访问。 现在想象一下试图同时去洗手间的两个过程。 那不是一个好情况,并且使用信号量来防止这种情况。 不幸的是,信号量是一种自愿机制,过程(我们的洗手间)可以忽略它(即,即使有钥匙,仍然有人可以将门打开)。 二进制/互斥量和计数信号量之间也存在差异。 在 http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html上 查看讲义。 #2楼 构建并发程序有两个基本概念-同步和互斥。 我们将看到这两种类型的锁(信号灯通常是一种锁定机制)如何帮助我们实现同步和互斥。 信号量是一种编程结构,可通过实现同步和互斥来帮助我们实现并发。 信号量有两种类型,二进制和计数。 信号量包括两个部分:一个计数器和一个等待访问特定资源的任务列表。 信号量执行两项操作:wait(P)[就像获取锁一样],以及release(V)[类似于释放锁] –这是一个可以对信号量执行的仅有的两项操作。 在二进制信号量中,计数器在逻辑上介于0和1之间。您可以认为它类似于具有两个值的锁:打开

pythonの多线程

↘锁芯ラ 提交于 2020-03-10 11:55:30
python的GIL 在非python环境中,单核情况下,同时只能有一个任务执行。多核时可以支持多个线程同时执行。 在python中,无论有多少核,同时只能执行一个线程,这是由于GIL所导致的。 GIL(Global Interpreter Lock全局解释器锁),是为了数据安全所做的决定,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”。 在一个python进程中,GIL只有一个 拿不到GIL的线程,就不允许进入CPU执行 GIL的释放逻辑 python2.x中,在线程遇见IO操作或者ticks计数达到100时进行释放(ticks是python自身的一个计数器,专门用于做GIL,每次释放后归零,这个计数可以通过sys.setcheckinterval来调整) python3.x中,改为使用计时器(当执行时间达到阈值后,当前线程释放GIL) 释放GIL锁后,线程会进行锁竞争,随后切换线程,会消耗资源 由于python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行),所以在多核CPU上,python的多线程效率并不高 python多线程工作过程 1.拿到公共数据 2.申请GIL 3.python解释器调用os原生线程 4.os操作cpu执行运算 5.当该线程达到gil的释放要求时,无论运算是否已经执行完,gil都被要求释放 6.其他线程重复上面的过程