互斥锁

多线程执行sql报错处理

匿名 (未验证) 提交于 2019-12-02 23:47:01
原文: https://www.cnblogs.com/heiao10duan/p/9373237.html 参考: https://www.jianshu.com/p/60c8e0e440ea 原因: 使用了多线程,多线程共享了同一个数据库连接,但每个execute前没有加上互斥锁 方法: 方法一:每个execute前加上互斥锁 lock.acquire() cursor.execute(command,data) lock.release() 1 2 3 方法二: 每个线程拥有自己的数据库连接,即在线程调用函数中加上数据库连接代码 方法三: 所有线程共用一个连接池,需要考虑线程总数和连接池连接数上限的问题未加互斥锁之前: 加了互斥锁之后:

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

python中的GIL锁与线程互斥锁的区别

陌路散爱 提交于 2019-12-02 15:08:59
python中的GIL锁与线程互斥锁的区别 GIL锁: GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有。 互斥锁 那么多线程编程时通过调用threading模块的Lock函数,来获取一把互斥锁。 互斥锁就是对共享数据进行锁定,保证同一时刻只有一个线程操作数据。 GIL锁的释放 在python3.x中,GIL不使用ticks计数,改为使用计时器(执行时间达到阈值后,当前线程释放GIL),这样对CPU密集型程序更加友好,但依然没有解决GIL导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。 那么下来用代码来解释互斥锁与GIL锁的区别 假设有这样一个场景: import threading # 定义全局变量 g_num = 0 # 循环一次给全局变量加1 def sum_num1 ( ) : for i in range ( 1000000 ) : global g_num g_num += 1 print ( "sum1:" , g_num ) # 循环一次给全局变量加1 def sum_num2

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:创建单例 //注意

自旋锁与互斥锁

人走茶凉 提交于 2019-12-02 05:53:20
自旋锁与互斥锁 理论分析 互斥锁的问题 自旋锁应用场景 自旋锁实践 总结 自旋锁与互斥锁 自旋锁和互斥锁是多线程程序中的重要概念。 它们被用来锁住一些共享资源, 以防止并发访问这些共享数据时可能导致的数据不一致问题。 但是它们的不同之处在哪里? 我们应该在什么时候用自旋锁代替互斥锁? 理论分析 从理论上说, 如果一个线程尝试加锁一个互斥锁的时候没有成功, 因为互斥锁已经被锁住了, 这个未获取锁的线程会休眠以使得其它线程可以马上运行。 这个线程会一直休眠, 直到持有锁的线程释放了互斥锁, 休眠的线程才会被唤醒。 如果一个线程尝试获得一个自旋锁的时候没有成功, 该线程会一直尝试加锁直到成功获取锁。 因此它不允许其它线程运行(当然, 操作系统会在该线程所在的时间片用完时, 强制切换到其它线程)。 互斥锁的问题 互斥锁存在的问题是, 线程的休眠和唤醒都是相当昂贵的操作, 它们需要大量的CPU指令, 因此需要花费一些时间。 如果互斥量仅仅被锁住很短的一段时间, 用来使线程休眠和唤醒线程的时间会比该线程睡眠的时间还长, 甚至有可能比不断在自旋锁上轮训的时间还长。自旋锁的问题是, 如果自旋锁被持有的时间过长, 其它尝试获取自旋锁的线程会一直轮训自旋锁的状态, 这将非常浪费CPU的执行时间, 这时候该线程睡眠会是一个更好的选择。 自旋锁应用场景 在单核/单CPU系统上使用自旋锁是没用的,

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

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

这风景如画,院子里花洒

与世无争的帅哥 提交于 2019-12-02 00:08:53
互斥锁: 进程之间的数据是不共享的,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端是没有问题的,而共享带来的竞争,竞争带来的结果就是错乱,因此我们上个锁. 锁可以让多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,牺牲了速度保证了数据的安全 进程间通信: 我们知道进程之间数据是相互隔离的,要想实现进程间的通信,就必须借助于一些技术才可以,比如木楼梯processing 模块中的,对列和管道,这两种方法v都是可以实现进程间数据传输的 ,由于队列是管道假锁 方式实现,所以我们看重研究队列即可. 创建共享的进程队列,queue是多进程安全的队列,可以使用queue实现多进程之间的数据传递. 生产者与消费者: 在并发编程中使用生产者模式能够解决大部分并发问题.该模式下通过平衡生产线和消费线程的工作能力来提高程序的整体处理数据的速度 什么是生产者消费者模式 就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通信,而通过阻塞队列来进行通信 爲什麽使用生產者和消費者模式 在綫程世界裏,生產者就是生產數據的綫程,消費者就是消費數據的綫程,在多綫程開發中,如果生產者處理速度很快,爾消費者處理速度很慢,生產者就得等消費者,爲了解決這樣的問題,引入了生產者和消費者模式 綫程: 什麽是綫程 在傳統操作系統中,每個進程有一個地址空間

博客整理day29

余生颓废 提交于 2019-12-02 00:02:13
目录 python day29 进程互斥锁 进程间通信 队列 生产者消费者模型 线程 什么是线程 为什么要是用线程 开启线程的方式 线程对象的属性 线程互斥锁 python day29 进程互斥锁 ​ 枷锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,虽然牺牲了执行效率,保证了数据安全 ​ 在程序并发执行时,需要修改数据时使用 ''' 模拟抢票软件需求: 并发查票与抢票 1.查看余票 2.开始抢票 进程互斥锁: 让并发变成串行, 牺牲了执行效率, 保证了数据安全. 在程序并发执行时,需要修改数据时使用. ''' import json from multiprocessing import Process from multiprocessing import Lock def search(user): with open('data.txt','r',encoding='utf8') as f: dic = json.load(f) print(f'{user}查询余票,还剩余{dic["ticket_num"]}') def buy(user): with open('data.txt','r',encoding='utf8') as f: dic = json.load(f) if dic['ticket_num'] > 0: dic[

1022 笔记

心已入冬 提交于 2019-12-01 23:50:08
目录 一 .进程互斥锁 并发变串行 lock 进程锁/互斥锁 总结 二 .IPO机制 1.管道 2.队列 1. Queue() 2. put() 3. q.get() 4. empty() 5. q.get_nowait() 6. q.put_nowait() 7. q.full() 3.进程间通信 三 . 生产者消费者模型 四 .线程 1.定义 2.为什么要使用线程 开启进程 开启线程 3.线程的创建 方式1 方式2 4.属性方法 1. current_thread.name() 2. isAlive 3. .daemon = True 4.线程互斥锁 一 .进程互斥锁 并发变串行 让并发变成串行,牺牲了执行效率,保证了数据的安全在程序并发执行时,需要修改数据时使用. 运行时出现全部购票成功的情况(余票为1),是因为并发编程,每个子进程都获得res为1,每个都以自己的res执行get,最后成功购票,可以在p.start后面加上p.join使其变为串行,前面结束才能运行后面的 from multiprocessing import Process import json,time def search(): '''查询余票''' time.sleep(1) with open('db.txt','r',encoding='utf-8') as f: res = json.load

Python3 并发编程2

别等时光非礼了梦想. 提交于 2019-12-01 23:44:07
目录 进程互斥锁 基本概念 互斥锁的使用 IPC 基本概念 队列 生产者消费者模型 基本概念 代码实现 线程 基本概念 创建线程 线程互斥锁 进程互斥锁 基本概念 临界资源: 一次仅允许一个进程使用的资源称为临界资源, 进程间采取互斥的方式, 共享临界资源 进程互斥: 一个进程正在访问临界资源, 另一个要访问该资源的进程必须等待 让并发变成串形, 牺牲了执行效率, 保证了数据的安全 在程序并发执行时, 需要修改时使用 互斥锁的使用 # base_data--->{"ticket_num": 1} # 模拟抢票软件 import json import time from multiprocessing import Process # 查看余票 def search(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) ticket_num = dic.get('ticket_num') print(f'用户{user}正在查看余票, 当前余票{ticket_num}张...') # 购买车票 def buy(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) # 阻塞 time