条件变量

Linux线程间同步的几种方式

匿名 (未验证) 提交于 2019-12-02 21:56:30
信号量强调的是线程(或进程)间的同步:“信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在sem_wait的时候,就阻塞在那里)。当信号量为单值信号量时,也可以完成一个资源的互斥访问。信号量测重于访问者对资源的有序访问,在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。 可以用于不同进程间或多线程间的互斥与同步 创建打开有名信号量 sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); //成功返回信号量指针;失败返回SEM_FAILED,设置errno name是文件路径名,但不能写成/tmp/a.sem这样的形式,因为在linux下,sem都是在/dev/shm目录下,可写成"/mysem"或"mysem",创建出来的文件都是"/dev/shm/sem.mysem",mode设置为0666,value设置为信号量的初始值.所需信号灯等已存在条件下指定O_CREAT|O_EXCL却是个错误。 关闭信号量,进程终止时,会调用它 int sem_close(sem

Java核心技术36讲 - 学习笔记

匿名 (未验证) 提交于 2019-12-02 21:53:52
数据结构 底层实现 线程安全 性能 支持null键值 HashTable 基于哈希表 是 put/get/remove-o(1) 不支持 HashMap 基于哈希表 否 put/get/remove-o(1) 支持 TreeMap 基于红黑树 否 put/get/remove-o(log n) 不支持null键,支持null值 ConcurrentHashMap 锁分段技术 是 并发环境下优于同步版本的集合 不支持 创建型模式,解决对象创建的各种问题,如工厂、单例、构建器(Builder)、原型; 结构型模式,是对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验,如装饰者、外观、组合、适配器、桥接、代理; 行为型模式,是从类和对象之间交互、职责划分等方面总结的模式,如策略、观察者、命令、迭代器、模板方法、访问者。 JDK的IO框架运用了装饰者模式(特征:一系列的类以相同的抽象类或者接口作为其构造函数的入参)。如:InputStream <- FilterInputStream <- BufferedInputStream。 GUI、Swing等的组件事件监听,运用了观察者模式。 新版JDK中HTTP/2 Client API,创建HttpRequest,运用了构建器模式,通常被实现成fluent风格的API,也叫方法链。

iOS: 线程中那些常见的锁

拟墨画扇 提交于 2019-12-02 06:13:15
一、介绍 在多线程开发中,锁的使用基本必不可少,主要是为了解决资源共享时出现争夺而导致数据不一致的问题,也就是线程安全问题。锁的种类很多,在实际开发中,需要根据情况选择性的选取使用,毕竟使用锁也是消耗CPU的。 本人虽然一直有使用多线程进行开发,但是对于锁的使用和理解并不是特别的深入,这不看到一篇挺mark的博客: https://www.jianshu.com/p/a236130bf7a2 ,在此基础上稍添加点东西转载过来(尊重原创),一是为了记录便于随时翻阅,而是为了写一遍加深印象,知识都是一个copy和attract的过程。 二、种类 1、互斥锁 概念:对共享数据进行锁定,保证同一时刻只能有一个线程去操作。 抢到锁的线程先执行,没有抢到锁的线程就会被挂起等待。 等锁用完后需要释放,然后其它等待的线程再去抢这个锁,那个线程抢到就让那个线程再执行。 具体哪个线程抢到这个锁是由cpu调度决定的。 常用: @synchronized:同步代码块 example:执行操作 /** *设置属性值 */ -(void)setMyTestString:(NSString *)myTestString{ @synchronized(self) { // todo something _myTestString = myTestString; } } example:创建单例 //注意

Linux中的各种锁及其基本原理

风流意气都作罢 提交于 2019-12-02 04:56:37
Linux中的各种锁及其基本原理 1.概述 通过本文将了解到如下内容: Linux系统的并行性特征 互斥和同步机制 Linux中常用锁的基本特性 互斥锁和条件变量 2.Linux的并行性特征 Linux作为典型的多用户、多任务、抢占式内核调度的操作系统,为了提高并行处理能力,无论在内核层面还是在用户层面都需要特殊的机制来确保任务的正确性和系统的稳定运行,就如同一个国家需要各种法律条款来约束每个公民的行为,才能有条不紊地运转。 在内核层面涉及到各种软硬件中断、进线程睡眠、抢占式内核调度、多处理器SMP架构等,因此内核在完成自己工作的时候一直在处理这些资源抢占的冲突问题。 在用户层面的进程,虽然Linux作为虚地址模式操作系统,为每个进程开辟了独立的虚拟地址空间,伪独占式拥有资源,但是仍然存在很多场景不得不产生多个进程共享资源的问题,来完成进程间的通信,但是在Go语言中进程间的通信使用消息来完成,处理地更优雅一些。 在线程层面,线程作为进程的一部分,进程内的多个线程只拥有自己的独立堆栈等少量结构,大部分的资源还是过线程共享,因此多线程的资源占用冲突比进程更加明显,所以多线程编程的线程安全问题是个重难点。综上可知,无论在kernel还是user space都必须有一些机制来确保对于资源共享问题的解决,然后这个机制就是接下来要说的:同步和互斥。 3.同步和互斥机制 基本概念

[TLPI] C30 Threads: Thread Synchronization

旧城冷巷雨未停 提交于 2019-12-01 19:18:41
目录 THREADS: THREAD SYNCHRONIZATION Protecting Accesses to Shared Variables: Mutexes Statically Allocated Mutexes Locking and Unlocking a Mutex Performance of Mutexes Mutex Deadlocks Dynamically Initializing a Mutex Mutex Attributes Mutex Types Signaling Changes of State: Condition Variables Statically Allocated Condition Variables Singaling and Waiting on Condition Variables Testing a Condition Variable's Predicate THREADS: THREAD SYNCHRONIZATION Protecting Accesses to Shared Variables: Mutexes The term critical section is used to refer to a section of code that accesses a shared resource and

线程池的设计(一):半同步半异步线程池的设计

末鹿安然 提交于 2019-12-01 16:58:30
前置问答: 1.为什么要使用线程池? 避免大量创建和销毁线程,提升性能。 2.线程池主要工作流程?一是外部不断地向线程池添加任务,而是线程池内部不断地取任务执行,这是典型的生产者消费者模型。 3.线程池有几种类型?半同步半异步线程池 和 领导者追随者线程池。 第一部分: 半同步半异步线程池的工作流程: 代码实现: http://www.itdadao.com/2016/01/18/226136/ 1. 启动 :启动若干个线程,每个线程函数内部会循环从任务队列中取任务,任务队列的内容就是线程函数的函数名。 要点: a. 线程函数是需要传给线程池对象的,线程池只负责管理线程,并不关心具体的工作线程的任务内容。 b. 刚启动线程池,没有传入任何任务时,此时线程池内的所有工作者线程处于阻塞等待状态(使用条件变量和互斥量),等待任务的到来。使用while(m_running)进行循环等待,当m_running为false时即为线程池停止服务时。 2. 添加任务 :向线程池申请线程执行任务,线程池对象内部会想任务队列push一个任务。 要点: a. 向任务队列push任务时,同步队列内部会通过条件变量唤醒正在阻塞的等待任务的工作者线程。 条件变量的使用过程如下: ①. 拥有条件变量的线程获取互斥量; ②. 循环检查某个条件,如果条件不满足,则阻塞线程直到条件满足。如果条件满足,向下执行; ③.

互斥锁,信号量,条件变量,读写锁

*爱你&永不变心* 提交于 2019-12-01 10:19:05
互斥锁 互斥锁的特性: 1. 原子性:当有一个线程成功拿到了这个锁,其他线程都无法在相同的时间拿到这个锁 2. 唯一性:在一个线程拿到锁的这段时间,只有当这个线程把锁释放掉,其他的线程才有可能拿到 3. 非繁忙等待性:如果一个线程已经锁定了一个互斥量,第二个线程又视图去拿到这个锁的前线,则第二个锁将被挂起,等待第一个线程对互斥量解锁位置,同时第二个线程获取锁,继续往下执行 pthread_mutex_init pthread_mutex_lock pthread_mutex_trylock pthread_mutex_unlock pthread_mutex_destroy 信号量 信号量相当于一个加强版的互斥锁,提高了共同访问共享资源的线程数目(从串行,变成了并行) sem_init sem_wait sem_trywait sem_post sem_getvalue sem_destroy 条件变量 自动阻塞一个线程,直到某种特殊的情况发生为止,通常条件变量和互斥锁相互配合使用。 条件变量使得我们可以睡眠等待某种条件出现,条件变量是利用线程间共享的全局变量进行同步的一个机制。 条件变量主要包括两个动作: 1. 一个线程等待 “条件变量的成立“ 2. 另一个线程使得 “条件成立” 条件变量的作用: 1. 先把调用线程放到等待条件的队列上 2. 释放指定的锁以提供其他线程添加任务

C++11并行编程-条件变量(condition_variable)详细说明

徘徊边缘 提交于 2019-12-01 09:11:45
<condition_variable > 头文件主要包含有类和函数相关的条件变量。 包括相关类 std::condition_variable 和 std::condition_variable_any ,还有枚举类型 std::cv_status 。另外还包含函数 std::notify_all_at_thread_exit() ,以下分别介绍一下以上几种类型。 std::condition_variable 类介绍 std::condition_variable 是条件变量,很多其它有关条件变量的定义參考维基百科。 Linux 下使用 Pthread 库中的 pthread_cond_*() 函数提供了与条件变量相关的功能, Windows 则參考 MSDN 。 当 std::condition_variable 对象的某个 wait 函数被调用的时候,它使用 std::unique_lock (通过 std::mutex ) 来锁住当前线程。 当前线程会一直被堵塞。直到另外一个线程在同样的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程。 std::condition_variable 对象通常使用 std::unique_lock<std::mutex> 来等待,假设须要使用另外的 lockable 类型

线程2——条件变量

╄→гoц情女王★ 提交于 2019-12-01 08:44:31
动态创建条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); 注销一个条件变量 int pthread_cond_destroy(pthread_cond_t *cond); 无条件等待 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 计时等待 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec*abstime); 发送单个条件变量成立信号 int pthread_cond_signal(pthread_cond_t *cond) 广播条件变量成立信号 int pthread_cond_ broadcast (pthread_cond_t *cond) 1 #include <pthread.h> 2 #include <stdio.h> 3 #include <unistd.h> 4 #include <stdlib.h> 5 #include <sys/time.h> 6 //声明两个线程 7 void* task1(void *arg); 8

Java线程之Lock

我是研究僧i 提交于 2019-11-30 22:20:49
重入锁 Java中的重入锁(即ReentrantLock)与Java内置锁一样,是一种排它锁。使用synchronized的地方一定可以用ReentrantLock代替。 重入锁需要显示请求获取锁,并显示释放锁。为了避免获得锁后,没有释放锁,而造成其它线程无法获得锁而造成死锁,一般建议将释放锁操作放在finally块里,如下所示。 123456 try{ renentrantLock.lock(); } finally { renentrantLock.unlock();} 如果重入锁已经被其它线程持有,则当前线程的lock操作会被阻塞。除了lock()方法之外,重入锁(或者说锁接口)还提供了其它获取锁的方法以实现不同的效果。 lockInterruptibly() 该方法尝试获取锁,若获取成功立即返回;若获取不成功则阻塞等待。与lock方法不同的是,在阻塞期间,如果当前线程被 打断(interrupt) 则该方法抛出InterruptedException。该方法提供了一种解除死锁的途径。 tryLock() 该方法试图获取锁,若该锁当前可用,则该方法立即获得锁并立即返回true;若锁当前不可用,则立即返回false。该方法 不会阻塞 ,并提供给用户对于成功获利锁与获取锁失败进行不同操作的可能性。 tryLock(long time, TimeUnit unit)