互斥锁

重新学习MySQL数据库6:浅谈MySQL的中事务与锁

陌路散爱 提交于 2019-11-28 10:36:27
『浅入深出』MySQL 中事务的实现 在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的;在这篇文章中,我们将对事务的实现进行分析,尝试理解数据库是如何实现事务的,当然我们也会在文章中简单对 MySQL 中对 ACID 的实现进行简单的介绍。 事务其实就是并发控制的基本单位;相信我们都知道,事务是一个序列操作,其中的操作要么都执行,要么都不执行,它是一个不可分割的工作单位;数据库事务的 ACID 四大特性是事务的基础,了解了 ACID 是如何实现的,我们也就清除了事务的实现,接下来我们将依次介绍数据库是如何实现这四个特性的。 原子性 在学习事务时,经常有人会告诉你,事务就是一系列的操作,要么全部都执行,要都不执行,这其实就是对事务原子性的刻画;虽然事务具有原子性,但是原子性并不是只与事务有关系,它的身影在很多地方都会出现。 由于操作并不具有原子性,并且可以再分为多个操作,当这些操作出现错误或抛出异常时,整个操作就可能不会继续执行下去,而已经进行的操作造成的副作用就可能造成数据更新的丢失或者错误。 事务其实和一个操作没有什么太大的区别,它是一系列的数据库操作(可以理解为 SQL)的集合,如果事务不具备原子性,那么就没办法保证同一个事务中的所有操作都被执行或者未被执行了

重新学习Mysql数据库2:『浅入浅出』MySQL 和 InnoDB

☆樱花仙子☆ 提交于 2019-11-28 10:34:29
作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite 还是工程上使用非常广泛的 MySQL、PostgreSQL,但是一直以来也没有对数据库有一个非常清晰并且成体系的认知,所以最近两个月的时间看了几本数据库相关的书籍并且阅读了 MySQL 的官方文档,希望对各位了解数据库的、不了解数据库的有所帮助。 ![](https://img2018.cnblogs.com/blog/1092007/201908/1092007-20190824162501679-1707813820.png) 添加描述 本文中对于数据库的介绍以及研究都是在 MySQL 上进行的,如果涉及到了其他数据库的内容或者实现会在文中单独指出。 数据库的定义 很多开发者在最开始时其实都对数据库有一个比较模糊的认识,觉得数据库就是一堆数据的集合,但是实际却比这复杂的多,数据库领域中有两个词非常容易混淆,也就是数据库和实例: 数据库:物理操作文件系统或其他形式文件类型的集合; 实例:MySQL 数据库由后台线程以及一个共享内存区组成; 对于数据库和实例的定义都来自于 MySQL 技术内幕:InnoDB 存储引擎 一书,想要了解 InnoDB 存储引擎的读者可以阅读这本书籍。 数据库和实例 在 MySQL 中,实例和数据库往往都是一一对应的,而我们也无法直接操作数据库

linux同步机制

淺唱寂寞╮ 提交于 2019-11-28 08:34:14
1、自旋锁 获得自旋锁之后禁止内核抢占,但可以被中断上半部打断。运行于中断上下文 单cpu不可抢占内核:空操作 单cpu可抢占内核:禁止内核抢占,不发生自旋 多cpu可抢占内核:禁止内核抢占+自旋 2、互斥锁 内核可以抢占,可以被其他进程抢占,运行于进程上下文 3、读写锁 由于其特殊的逻辑使得其效率相对普通的互斥锁和自旋锁要慢一个数量级,按POSIX标准 在线程申请读锁并未释放前本线程申请写锁是成功的,但运行后的逻辑结果是无法预测。读和写同时获取锁,写具有优先获取。特殊的自旋锁,禁止抢占。 4、顺序锁 对读写锁的一种优化,禁止内核抢占,读和写可以同时进行,多个读者可以同时访问临界资源,但不能同时写 读写可以同时进行这是读写锁不具备的,但使用顺序锁也有限制条件:访问的临界资源不能是指针 5、RCU(read-copy update) 读写可以同时进行,写数据时,先拷贝然后修改,再用更新好的数据覆盖原有数据。 同样获得锁之后禁止内核抢占 6、递归锁 互斥锁的一个特例,互斥锁设置参数PTHREAD_MUTEX_RECURSIVE_NP,运行互斥锁递归加锁和释放锁 7、原子操作 8、信号量 9、信号 10、barrier(信号屏障) barrier()函数前后的代码执行不能越过barrier 来源: https://www.cnblogs.com/zhu-g5may/p/11402395

并发通信(进程与线程)

社会主义新天地 提交于 2019-11-28 08:23:36
进程与线程在通信中都会遇到各自的问题,这是因他们各自的性质而产生的。每个进程有自己的地址空间,两个进程中的地址即使值相同,实际指向的位置也不同,故进程间 无法直接就能通信 。虽然同一进程的线程共享全局变量和内存,使得线程之间共享数据很容易也很方便,但会带来某些 共享数据的互斥问题 。下面用代码来值观地展示各自的问题。 进程通信限制: import multiprocessing def func(): global a a = 2 if __name__ == '__main__':#window系统用进程线程要加上这句 a = 1 proc = multiprocessing.Process(target=func) proc.start() proc.join()#确保子进程结束再打印a值 print(a) 1 可以发现,主进程的变量,即使在子进程中声名为全局变量,但由于互不干扰的内存地址空间而造成两个进程间完全失去了联系,故在子进程中是始终都无法修改到全局变量a的值。 进程通信解决方法: 为解决这个问题,在进程模块中引入了一个管理器,这个管理器可以开辟一个进程间共享的内存空间,这个空间的类型可以是列表、字典、队列。最常用的类型就是队列了,它是专门用于进程线程通信的数据结构,后面会详细介绍到。在开启进程时,我们可以将这个共享内存空间当作参数传入进程中,就可以对其操作

互斥锁,多进程之间的通信

好久不见. 提交于 2019-11-28 08:12:59
目录 1. 互斥锁 2. 进程之间的通信 2.1 基于文件的通信 2.2 基于队列的通信 3. 生产者消费者模型 1. 互斥锁 ​ 当多个进程抢占同一数据时,将数据加锁,使进程按串行的方式去获取数据,先到先得,保证了公平、数据的安全。 ​ lock.acquire() # 加锁 ​ lock.release() # 释放 ​ 死锁:连续lock.acquice() 多次,会阻塞进程。 # 模拟三个用户使用同一个打印机打印。 from multiprocessing import Process from multiprocessing import Lock # 导入互斥锁 import os import time import random import sys def task1(lock): lock.acquire() # 加锁 print(f'task1-{os.getpid()}开始打印!') time.sleep(random.randint(1,3)) print(f'task1-{os.getpid()}打印结束!') lock.release() # 解锁释放 def task2(lock): lock.acquire() print(f'task2-{os.getpid()}开始打印!') time.sleep(random.randint(1,3))

python进阶(4)

一世执手 提交于 2019-11-28 07:18:34
python进阶(4) 线程 线程的注意点 子线程之间共享全局变量,就会造成资源的争抢问题 互斥锁的问题 问题: 因为线程之间共享全局变量,所以,在多线程几乎在同时运行的时候,几乎同时修改同一全局变量的时候没,就要进行控制 此时,需要互斥锁 当某个线程需要修改资源的时候,先将资源进行锁定,其他线程不能修改该线程 当线程修改完成之后,并且释放完互斥锁之后,其他的线程才可以使用 互斥锁保证当前只有一个线程可以使用修改同一个资源 import threading num = 0 def add_num1 ( ) : global num for i in range ( 10000000 ) : lock . acquire ( True ) num += 1 lock . release ( ) print ( '子线程1已经完成,此时得到的num1' , num ) def add_num2 ( ) : global num for i in range ( 10000000 ) : lock . acquire ( ) num += 1 lock . release ( ) print ( '子线程2已经完成,此时得到的num2' , num ) if __name__ == '__main__' : lock = threading . Lock ( ) thread1 =

别说谁变了你拦得住时间么 提交于 2019-11-28 05:23:52
【同步】:   是指散步在不同任务之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。最基本的场景就是:两个或两个以上的进程或线程在运行过程中协同步调,按预定的先后次序运行。比如 A 任务的运行依赖于 B 任务产生的数据。 【互斥】:   是指散步在不同任务之间的若干程序片断,当某个任务运行其中一个程序片段时,其它任务就不能运行它们之中的任一程序片段,只能等到该任务运行完这个程序片段后才可以运行。最基本的场景就是:一个公共资源同一时刻只能被一个进程或线程使用,多个进程或线程不能同时使用公共资源。 【互斥锁的特点】: 1. 原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量; 2. 唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量; 3. 非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。 【互斥锁的操作流程如下】: 1. 在访问共享资源后临界区域前,对互斥锁进行加锁; 2. 在访问完成后释放互斥锁导上的锁

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

六眼飞鱼酱① 提交于 2019-11-28 04:14:45
目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.getppid() tasklist tasklist| findstr 进程名 3.进程与进程之间是有物理隔离: 不能共享内存的数据.(lock,队列) 4.join阻塞: 让主进程等待子进程结束之后,在执行. 5.其他属性: terminate() is_alive() name, 6.守护进程: 将子进程设置成守护进程,当主进程结束了,子进程就马上结束. 2.僵尸进程和孤儿进程 2.1僵尸进程 僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵尸进程. #基于unix环境(linux,macOS) #主进程需要等待子进程结束之后,主进程才结束

线程同步

删除回忆录丶 提交于 2019-11-28 01:01:42
同步概念 所谓同步,即同时起步,协调一致。不同的对象,对“同步”的理解方式略有不同。如,设备同步,是指在两个设备之间规定一个共同的时间参考;数据库同步,是指让两个或多个数据库内容保持一致,或者按需要部分保持一致;文件同步,是指让两个或多个文件夹里的文件保持一致。等等 而,编程中、通信中所说的同步与生活中大家印象中的同步概念略有差异。“同”字应是指协同、协助、互相配合。主旨在协同步调,按预定的先后次序运行。 线程同步 同步即协同步调,按预定的先后次序运行。 线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2: 内存中100字节,线程T1欲填入全1, 线程T2欲填入全0。但如果T1执行了50个字节失去cpu,T2执行,会将T1写过的内容覆盖。当T1再次获得cpu继续 从失去cpu的位置向后写入1,当执行结束,内存中的100字节,既不是全1,也不是全0。 产生的现象叫做“与时间有关的错误”(time related)。为了避免这种数据混乱,线程需要同步。 “同步”的目的,是为了避免数据混乱,解决与时间有关的错误。实际上,不仅线程间需要同步,进程间、信号间等等都需要同步机制。 因此, 所有“多个控制流

GIL锁 与线程进程池

拟墨画扇 提交于 2019-11-27 21:22:35
GIL GIL锁: 全局解释器锁. Cpython特有的一把互斥锁,自动加锁解锁 将并发变成串行同一时刻同一进程中只有一个线程被执行使用共享资源 ,牺牲效率,保证数据安全. 同一个进程中的多个线程只能有一个线程真正被cpu执行 设置全局解释锁: GIL 保证解释器里面的数据安全. 当时开发py语言时,只有单核, 强行加锁: 减轻了你开发的人员的负担. 单个进程多线程不能利用多核,为什么不去掉? 不能去掉,源码太多,改不动了 不能用多核会影响效率吗 看处理数据情况 我们有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是: 方案一:开启四个进程 方案二:一个进程下,开启四个线程 #单核情况下,分析结果:   如果四个任务是计算密集型,没有多核来并行计算,方案一徒增了创建进程的开销,方案二胜   如果四个任务是I/O密集型,方案一创建进程的开销大,且进程的切换速度远不如线程,方案二胜 #多核情况下,分析结果:   如果四个任务是计算密集型,多核意味着并行计算,在python中一个进程中同一时刻只有一个线程执行用不上多核,方案一胜   如果四个任务是I/O密集型,再多的核也解决不了I/O问题,方案二胜 #结论:现在的计算机基本上都是多核,python对于计算密集型的任务开多线程的效率并不能带来多大性能上的提升,甚至不如串行(没有大量切换),但是