信号量

无名信号量在多线程间的同步

喜夏-厌秋 提交于 2019-12-26 11:04:01
//无名信号量的常见用法是将要保护的变量放在sem_wait和sem_post中间所形成的临界区内,这样该变量就会被//保护起来,例如: #include <pthread.h> #include <semaphore.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> int number; // 被保护的全局变量 sem_t sem_id; void* thread_one_fun(void *arg) { sem_wait(&sem_id); printf("thread_one have the semaphore\n"); number++; printf("number = %d\n",number); sem_post(&sem_id); } void* thread_two_fun(void *arg) { sem_wait(&sem_id); printf("thread_two have the semaphore \n"); number--; printf("number = %d\n",number); sem_post(&sem_id); } int main(int argc,char *argv[]) { number = 1; pthread_t id1, id2;

信号量与互斥锁

故事扮演 提交于 2019-12-25 03:01:19
学习Mutex的心得,不一定对,先记录一下。 同步技术分为两大类,锁定和信号同步。 锁定分为:Lock、Monitor 信号同步分为:AutoResetEvent、ManualResetEvent、Semaphore以及Mutex。他们都继承自WaitHandle, AutoResetEvent、ManualResetEvent在内存中维护一个布尔型变量,如果为false则阻塞,如果为true则解除阻塞 Semaphore在内存中维护一个整型变量,如果为0则阻塞,如果大于0则解除阻塞,每解除一个阻塞其值减一 AutoResetEvent、ManualResetEvent、Semaph提供单进程内的线程同步 Mutex提供跨应用程序域的线程阻塞和解除的能力,主要用于互斥访问。 下面是一个使用Mutex进行互斥访问的演示例子。 软件打开时,如果接收到输入则创建一个互斥锁,并持有锁,直到再次接收到输入,然后释放锁,如果再次输入又创建锁, 如此循环。 假设app1创建一个互斥锁,然后持有锁,并对共享资源进行操作,那么app2就不能再次创建互斥锁,据此就能判断共享资源释放被别的进程占用。 如果app1使用完了共享资源,释放了互斥锁,则app2就可以创建互斥锁,据此可以判断共享资源可以被访问了。 以下是app1代码 1、Mutex用于进程间的同步 using System; using

【JUC】JUC锁框架综述

蹲街弑〆低调 提交于 2019-12-25 01:58:24
一、前言   在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程。我们分为几个模块进行分析,首先是对锁模块的分析。 二、锁框架图   在Java并发中,锁是最重要的一个工具,因为锁,才能实现正确的并发访问,所以,先从锁入手一步步进行分析,锁的框架图如下。   说明:在锁结构框架中乃至并发框架中,AbstractQueuedSynchronizer都占有举足轻重的地位,同时LockSupport也是非常重要的类。 三、具体说明    3.1 Condition   Condition为接口类型,它将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。 可以通过await(),signal()来休眠/唤醒线程。    3.2 Lock   Lock为接口类型,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性

软开面试题合集--Binrry(冰蕊)

醉酒当歌 提交于 2019-12-24 13:39:27
线程和进程的区别 根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位 在开销方面:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。 所处环境:在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行(通过CPU调度,在每个时间片中只有一个线程执行) 内存分配方面:系统在运行的时候会为每个进程分配不同的内存空间;而对线程而言,除了CPU外,系统不会为线程分配内存(线程所使用的资源来自其所属进程的资源),线程组之间只能共享资源。 包含关系:没有线程的进程可以看做是单线程的,如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。 垃圾收集讲一下,1.8有哪些新特性 深入理解JVM垃圾收集机制(JDK1.8) JDK1.8 十大新特性详解 jvm调优有哪些参数 深入理解JVM-内存模型(jmm)和GC 深入详解JVM内存模型与JVM参数详细配置 tcp和udp,tcp网络架构 TCP与UDP的对比 TCP/IP架构 TCP/IP五层网络架构及OSI参考模型 nio与bio

Java中的信号量Semaphore

空扰寡人 提交于 2019-12-24 04:29:05
信号量的实现模型一般包括:1个计数器、1个等待队列、3个方法(需要保证原子性) Semaphore 实现的伪代码(JDK 中 Semaphore 是基于 AbstractQueuedSynchronizer 实现,可以指定是否公平): class Semaphore{ //计数器 int count; //等待队列 Queue queue; //初始化 Semaphore(int c){ this.count=c; } //获取许可证 void acquire(){ count--; if(count<0){ //将当前线程插入等待队列 //阻塞当前线程 } } //获取许可证 void release(){ count++; if(count<=0) { //移除等待队列中的某个线程 //唤醒某个线程 } } } 使用信号量实现互斥锁效果: package constxiong.interview; import java.util.concurrent.Semaphore; /** * 测试使用信号量实现锁的效果 * @author ConstXiong * @date 2019-12-18 14:18:47 */ public class TestSemaphore { private static int count; private static Semaphore

RT-Thread USB虚拟串口收发调试

我与影子孤独终老i 提交于 2019-12-24 01:11:19
学习过程中参考博文: 记录——基于 RT-Thread 实现 USB 虚拟串口 但是遇到了两个问题: 1.串口有设备,但是不能发送; 2.串口能发送但不能接收; 第一个问题,是因为rtt的usb虚拟串口默认启用了RTS和DTR(终端准备好接收): static rt_err_t _interface_handler ( ufunction_t func , ureq_t setup ) { struct vcom * data ; RT_ASSERT ( func != RT_NULL ) ; RT_ASSERT ( func -> device != RT_NULL ) ; RT_ASSERT ( setup != RT_NULL ) ; data = ( struct vcom * ) func -> user_data ; switch ( setup -> bRequest ) { case CDC_SEND_ENCAPSULATED_COMMAND : break ; case CDC_GET_ENCAPSULATED_RESPONSE : break ; case CDC_SET_COMM_FEATURE : break ; case CDC_GET_COMM_FEATURE : break ; case CDC_CLEAR_COMM_FEATURE : break ;

读者写者问题(读者优先、写者优先、公平竞争)

守給你的承諾、 提交于 2019-12-24 00:53:53
读者优先: 1.写者、读者互斥访问文件资源。 2.多个读者可以同时访问文件资源。 3.只允许一个写者访问文件资源。 具体实现: 1.设置信号量fileSrc实现读写者对临界资源的访问。 2.设置计数器readCount来统计访问临界资源的读者数目,设置信号量readCountSignal完成对readCount计数器资源的互斥访问。 / 初始化读者队列为0,文件资源的初始值为1 / int readCount = 0 ; semaphore readCountSignal = 1 ; reader() { while ( true ) { wait(readCountSignal); //申请读者队列计数器 if (!readCount) //如果读者队列为空,申请文件资源 wait(fileSrc); readCount++; signal(readCountSignal); //释放读者计数器资源 … perform read operation //执行临界区代码 … wait(readCountSignal); //申请读者计数器资源 readCount–; if (!readCount) //如果读者队列为空,释放文件资源 signal(fileSrc); signal(readCountSignal); //释放读者计数器资源 } } writer() { while

进程同步控制

你离开我真会死。 提交于 2019-12-23 23:43:12
锁——multiprocessing.Lock 什么是锁? 当多个进程使用同一份数据资源的时候,会引发数据安全或顺序混乱问题。这个时候我们希望进程可以一个一个的去获取和修改数据,将几个并发的进程编程串行,这样就可以保证数据的安全。我们可以引用Lock模块来帮我们来实现将异步执行的程序在加锁的代码段中同步去执行。 mport os import time import random from multiprocessing import Process def work(n): print('%s: %s is running' %(n,os.getpid())) time.sleep(random.random()) print('%s:%s is done' %(n,os.getpid())) if __name__ == '__main__': for i in range(3): p=Process(target=work,args=(i,)) p.start() 多进程抢占输出资源 # 由并发变成了串行,牺牲了运行效率,但避免了竞争 import os import time import random from multiprocessing import Process,Lock def work(lock,n): lock.acquire() print('%s:

Semaphore的使用及原理

风流意气都作罢 提交于 2019-12-22 17:16:29
前言 Semaphore也是JUC包中一个用于并发控制的工具类,举个常用场景的例子:有三台电脑五个人,每个人都要用电脑注册一个自己的账户,这时最开始只能同时有三个人操作电脑注册账户,这三个人中有人操作完了剩下的两个人才能占用电脑注册自己的账户。这就是Semaphore的经典使用场景,跟并发加锁有点像,只是我们的并发加锁同一时间只让有一个线程执行,而Semaphore的加锁控制是允许同一时间有指定数量的线程同时执行,超过这个数量就加锁控制。 一、使用样例 1 public static void main(String[] args) { 2 Semaphore semaphore = new Semaphore(3); // 对比上面例子中的3台电脑 3 for (int i = 0; i < 5; i++) { // 对比上面例子中的5个人 4 new Thread(() -> { 5 try { 6 semaphore.acquire(1); // 注意acquire中的值可以传任意值>=0的整数 7 } catch (InterruptedException e) { 8 e.printStackTrace(); 9 } 10 System.out.println(Thread.currentThread().getName() + " acquire 1"); 11 try

RT_Thread应用7—信号量1

血红的双手。 提交于 2019-12-22 03:42:33
第十九章 信号量(第一部分) 一、线程同步 同步的介绍: 同步 是指按预定的先后次序进行运行,线程同步是指多个线程通过特定的机制来控制线程之间的执行顺序,也可以说是在线程之间通过同步建立起执行顺序的关系,如果没有同步,那线程之间将是无序的。 线程同步的原因 在多任务实时系统中,一项工作的完成往往可以通过 多个任务 协调的方式共同来完成, 如一个任务从传感器中接收数据并且将数据写到共享内存中,同时另一个任务周期性的从共享内存中读取数据并发送去显示 如果对共享内存的访问不是排他性的,那么各个线程间可能同时访问它。这将引起数据一致性的问题, 例如:在显示线程 Thread#2 试图显示数据之前,传感器线程 Thread#1 还未完成数据的写入,那么显示将包含不同时间采样的数据,易造成显示数据的迷惑。 所以,需要先将传感器数据写入到共享内存完成后,才允许执行传感器数据从共享内存中读出的操作。 **对于操作/访问同一块区域,称之为临界区**。 任务的同步方式的 核心思想 都是: 在访问临界区的时候只允许一个(或一类)任务运行。 二、信号量基本概念 **概念:**信号量(Semaphore)是一种实现线程间通信的机制,实现线程之间同步或临界资源的互斥访问,常用于协助一组相互竞争的线程来访问临界资源。 信号量就像一把钥匙,把一段临界区给锁住,只允许有钥匙的线程进行访问:线程拿到了钥匙