互斥锁

关于【缓存穿透、缓存击穿、缓存雪崩、热点数据失效】问题的解决方案

早过忘川 提交于 2020-01-28 13:29:26
1 前言 在我们的平常的项目中多多少少都会使用到缓存,因为一些数据我们没有必要每次查询的时候都去查询到数据库。 特别是高 QPS 的系统,每次都去查询数据库,对于你的数据库来说将是灾难。 今天我们不牵涉多级缓存的知识,就把系统使用到的缓存方案,不管是一级还是多级的都统称为缓存,主要是为了讲述使用缓存的时候可能会遇到的一些问题以及一些解决办法。 我们使用缓存时,我们的业务系统大概的调用流程如下图: 当我们查询一条数据时,先去查询缓存,如果缓存有就直接返回,如果没有就去查询数据库,然后返回。这种情况下就可能会出现一些现象。 2 缓存穿透 2.1 什么是缓存穿透 正常情况下,我们去查询数据都是存在。 那么请求去查询一条压根儿数据库中根本就不存在的数据,也就是缓存和数据库都查询不到这条数据,但是请求每次都会打到数据库上面去。 这种查询不存在数据的现象我们称为 缓存穿透 。 2.2 穿透带来的问题 试想一下,如果有黑客会对你的系统进行攻击,拿一个不存在的id 去查询数据,会产生大量的请求到数据库去查询。可能会导致你的数据库由于压力过大而宕掉。 2.3 解决办法 2.3.1 缓存空值 之所以会发生穿透,就是因为缓存中没有存储这些空数据的key。从而导致每次查询都到数据库去了。 那么我们就可以为这些key对应的值设置为null 丢到缓存里面去。后面再出现查询这个key 的请求的时候

python进阶之多线程(简单介绍协程)

﹥>﹥吖頭↗ 提交于 2020-01-26 19:22:06
多线程 线程:实现多任务的另一种方式 一个进程中,也经常需要同时做多件事,就需要同时运行多个‘子任务’,这些子任务,就是线程 线程又被称为 轻量级进程 (lightweight process),是更小的执行单元 一个进程可拥有多个并行的(concurrent)线程,当中每一个线程,共享当前进程的资源 一个进程中的线程共享相同的内存单元/内存地址空间可以访问相同的变量和对象,而且它们从同一堆中分配对象通信、数据交换、同步操作 由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快 线程与进程的区别 一般来讲:我们把进程用来分配资源,线程用来具体执行(CPU调度) 多线程的创建(函数和类) 创建线程的两种方式: 第一:通过 threading.Thread 直接在线程中运行函数; import threading,time def saySorry(): print("子线程%s启动" %(threading.current_thread().name)) #当前线程的名字 time.sleep(1) print("我能吃饭了吗?") if __name__ == "__main__": print('主线程%s启动' %(threading.current_thread().name)) for i in range(5):

3 互斥锁

我与影子孤独终老i 提交于 2020-01-25 17:45:17
互斥锁的初始值为1; 通过互斥锁保护临界区的代码执行; 1、初始化 osSemaphoreId_t sem_mutex ; int count = 0 ; sem_mutex = osSemaphoreNew ( 1 , 1 , NULL ) ; 2、线程1 osSemaphoreAcquire ( sem_mutex , osWaitForever ) ; count ++ ; printf ( "%d\r\n" , count ) ; osSemaphoreRelease ( sem_mutex ) ; 3、线程2 osSemaphoreAcquire ( sem_mutex , osWaitForever ) ; count ++ ; printf ( "%d\r\n" , count ) ; osSemaphoreRelease ( sem_mutex ) ; 4、结论 来源: CSDN 作者: 小C菜鸟 链接: https://blog.csdn.net/C_cai_niao/article/details/103929518

Linux 平台多线程编程实例

落爺英雄遲暮 提交于 2020-01-25 09:28:53
转载请注明出去 http://blog.csdn.net/adong76/article/details/39828585 参考博客: http://www.cnblogs.com/armlinux/archive/2010/05/28/2396997.html http://blog.csdn.net/hitwengqi/article/details/8015646 http://www.vimer.cn/2009/11/linux%E4%B8%8B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%9A%84%E5%88%9B%E5%BB%BA%E4%B8%8E%E7%AD%89%E5%BE%85%E8%AF%A6%E8%A7%A3.html http://www.cnblogs.com/skynet/archive/2010/10/30/1865267.html http://www.cnblogs.com/vamei/archive/2012/10/09/2715393.html 最近在优化一个图像处理算法,算法中要对于不同的图片做相同的图像处理算法,不同图片之间的处理数据时独立的,因而很自然的想到利用多线程优化算法。 下面是一些学习代码 一 Linux下面的多线编程需要包含明白以下几点: 1 pthread_t pthread_t在头文件/usr

Linux 线程编程2.0——线程同步-互斥锁

落花浮王杯 提交于 2020-01-17 13:52:54
当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制。我们 可以创建一个读 / 写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取。     函数 pthread_mutex_init() 用来生成一个互斥锁。其函数原型如下: #include<pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex , const pthread_mutexattr_t *restrict attr) ; 第一个参数是互斥变量的地址,第二个参数设置互斥变量的属性,大多数情况下 . 选择 默认属性,则传入空指针 NULL 。   Pthread_mutex_lock() 函数声明开始用互斥锁上锁,此后的代码直至调用 pthread _mutex_ unlock() 为止,均被上锁,即同一时间只能被一个线程调用执行。当一个线程执行 到 pthread_mutex_lock() 处时,如果该锁此时被另一个线程使用,那么此线程被阻塞,线 程一直阻塞知道另一个线程释放此互斥锁。这两个函数原型是:  int pthread_mutex_lock(pthread_mutex_t *mutex) ;  int pthread_mutex_unlock(pthread_mutex_t *mutex) ;  

Linux多线程与同步

守給你的承諾、 提交于 2020-01-15 08:02:25
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 典型的UNIX系统都支持一个进程创建多个线程(thread)。在 Linux进程基础 中提到,Linux以进程为单位组织操作,Linux中的线程也都基于进程。尽管实现方式有异于其它的UNIX系统,但Linux的多线程在逻辑和使用上与真正的多线程并没有差别。 多线程 我们先来看一下什么是多线程。在 Linux从程序到进程 中,我们看到了一个程序在内存中的表示。这个程序的整个运行过程中,只有一个控制权的存在。当函数被调用的时候,该函数获得控制权,成为激活(active)函数,然后运行该函数中的指令。与此同时,其它的函数处于离场状态,并不运行。如下图所示: Linux从程序到进程 我们看到,各个方块之间由箭头连接。各个函数就像是连在一根线上一样,计算机像一条流水线一样执行各个函数中定义的操作。这样的一个程序叫做单线程程序。 多线程就是允许一个进程内存在多个控制权,以便让多个函数同时处于激活状态,从而让多个函数的操作同时运行。即使是单CPU的计算机,也可以通过不停地在不同线程的指令间切换,从而造成多线程同时运行的效果。如下图所示,就是一个多线程的流程: main()到func3()再到main()构成一个线程,此外func1()和func2()构成另外两个线程

java基础 锁

喜夏-厌秋 提交于 2020-01-14 07:50:47
一、乐观锁/悲观锁 乐观锁与悲观锁并不是特指某两种类型的锁,是人们定义出来的概念或思想,主要是指看待并发同步的角度。 (1)乐观锁: 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。 乐观锁适用于多读的应用类型 ,这样可以提高吞吐量,在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换)实现的。 ①数据版本机制   实现数据版本一般有两种,第一种是使用版本号,第二种是使用时间戳。以版本号方式为例。   版本号方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加1。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。 核心SQL代码: update table set xxx=#{xxx}, version=version+1 where id=#{id} and version=#{version}; ② CAS操作   CAS(Compare and Swap 比较并交换)

Linux线程(三)

假装没事ソ 提交于 2020-01-11 23:48:26
Linux线程(三) 一、互斥量 根据前面的分析,得到的结果不是我们想要的原因是–ticket操作不是原子操作,这个共享资源可能并发的切换大其他线程,导致有多个线程同时影响到这个共享资源,所以导致得到的结果不对。 1.解决方法(加锁—>Linux中叫这把锁为互斥量): 代码必须有互斥行为:当有一个执行流(有一个线程)进入临界区时,不允许其他线程进入该临界区 如果多个线程同时要求执行临界区的代码,并且临界区内没有线程在执行,那么只允许一个线程进入该临界区 如果线程不在临界区内执行,那么该线程不能阻止其他线程进入临界区 二、.互斥量的接口: 1.初始化互斥量 方法一:静态分配 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER 方法二:动态分配 int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 功能:初始化互斥量 参数:pthread_mutex_t *restrict mutex:要初始化的互斥量 const pthread_mutexattr_t *restrict attr:指定了新建互斥锁的属性。如果参数attr为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁 返回值

进程与线程

核能气质少年 提交于 2020-01-10 13:26:26
文章目录 进程与线程 进程通信 无名管道: 命名管道:FIFO 消息队列: 信号量: 共享内存: Socket通信: 线程之间的同步 互斥锁:互斥锁就是一种锁机制 条件变量 读写锁 自旋锁 信号量 总结: 进程与线程 概念:什么是线程:是操作系统能够进行运算调度的最小单位。什么是进程:是计算机中某一次数据集合的运行活动,是操作系统分配资源的最小单位。线程依赖于进程,进程就是线程的容器。 上面的描述比较官方,我的理解就是:想要通过计算机来完成某件事件那么你就得有一个进程来帮助你完成这个任务,也就是说,进程等价于利用计算机完成任务的一种手段,操作系统会为进程去分配各种资源,内存什么的,那么线程就是把进程分配成一个个小任务去执行,也就是说是进程执行的最小单位。 两个问题: 进程就是一个个跑在操作系统上的程序,那么如果想让两个进程或者多个进程之间通信怎么办? 线程是进程运行的最小单位,那么如果两个线程用到了同一个资源,怎么进行同步,否则这个资源的使用就乱套了 也就是说:进程要解决通信问题,否则就是单击小程序,线程要解决同步问题,也就是资源共享在线程中的问题。 进程通信 在Linux中进程通信有六种基本的方式: 无名管道: 是一种不属于任何文件系统的特殊文件,可以使用read和write 原型 #include <unistd.h>2 int pipe(int fd[2]); // 返回值

『浅入浅出』MySQL 和 InnoDB

﹥>﹥吖頭↗ 提交于 2020-01-09 11:41:03
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 作为一名开发人员,在日常的工作中会难以避免地接触到数据库,无论是基于文件的 sqlite 还是工程上使用非常广泛的 MySQL、PostgreSQL,但是一直以来也没有对数据库有一个非常清晰并且成体系的认知,所以最近两个月的时间看了几本数据库相关的书籍并且阅读了 MySQL 的官方文档,希望对各位了解数据库的、不了解数据库的有所帮助。 本文中对于数据库的介绍以及研究都是在 MySQL 上进行的,如果涉及到了其他数据库的内容或者实现会在文中单独指出。 数据库的定义 很多开发者在最开始时其实都对数据库有一个比较模糊的认识,觉得数据库就是一堆数据的集合,但是实际却比这复杂的多,数据库领域中有两个词非常容易混淆,也就是 数据库 和 实例 : 数据库:物理操作文件系统或其他形式文件类型的集合; 实例:MySQL 数据库由后台线程以及一个共享内存区组成; 对于数据库和实例的定义都来自于 MySQL 技术内幕:InnoDB 存储引擎 一书,想要了解 InnoDB 存储引擎的读者可以阅读这本书籍。 数据库和实例 在 MySQL 中,实例和数据库往往都是一一对应的,而我们也无法直接操作数据库,而是要通过数据库实例来操作数据库文件,可以理解为数据库实例是数据库为上层提供的一个专门用于操作的接口。 在 Unix 上,启动一个