互斥锁

python线程互斥锁Lock(29)

落爺英雄遲暮 提交于 2019-12-05 18:10:31
在前一篇文章 python线程创建和传参 中我们介绍了关于python线程的一些简单函数使用和线程的参数传递,使用多线程可以同时执行多个任务,提高开发效率,但是在实际开发中往往我们会碰到线程同步问题,假如有这样一个场景:对全局变量累加1000000次,为了提高效率,我们可以使用多线程完成,示例代码如下: # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解忧 @Blog(个人博客地址): shuopython.com @WeChat Official Account(微信公众号):猿说python @Github:www.github.com @File:python_thread_lock.py @Time:2019/10/17 21:22 @Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累! """ # 导入线程threading模块 import threading # 声明全局变量 g_num = 0 def my_thread1(): # 声明全局变量 global g_num # 循环 1000000 次,每次累计加 1 for i in range(0,1000000): g_num = g_num + 1 def my_thread2(): # 声明全局变量

C# 解决程序多次同时打开

≡放荡痞女 提交于 2019-12-05 16:36:54
使用互斥量 Mutex (命名空间:System.Threading) 互斥锁是同步对象,同一时间有且仅有一个线程可以获取它。 互斥锁可以适用于一个共享资源每次只能被一个线程访问。   相关的函数 创建一个处于未获取状态的互斥锁 Public Mutex() static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { //判断当前程序是否已经开启 bool falg = false; System.Threading.Mutex mutex = new System.Threading.Mutex(true, "Demo1",out falg); if (falg) //程序未开启 { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new HL_login()); } else //程序已经开启 { Model.PubDev.ShowMessage("程序已经打开!"); System.Threading.Thread.Sleep(3000); Environment.Exit(1);

python从入门到放弃之进程锁lock

。_饼干妹妹 提交于 2019-12-05 14:34:21
# ### lock (互斥锁) """ # 应用在多进程当中 # 互斥锁lock : 互斥锁是进程间的get_ticket互相排斥 进程之间,谁先抢占到资源,谁就先上锁,等到解锁之后,下一个进程在继续使用 """ lock.acquire()# 上锁 lock.release()# 解锁 #同一时间允许一个进程上一把锁 就是Lock 加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行(同步)的修改,没错,速度是慢了,但牺牲速度却保证了数据安全。 #同一时间允许多个进程上多把锁 就是[信号量Semaphore] 信号量是锁的变形: 实际实现是 计数器 + 锁,同时允许多个进程上锁 # 互斥锁Lock : 互斥锁就是进程的互相排斥,谁先抢到资源,谁就上锁改资源内容,为了保证数据的同步性 # 注意:多个锁一起上,不开锁,会造成死锁.上锁和解锁是一对. 代码如下 lock = Lock() # 上锁 lock.acquire() print(1) # 上锁和解锁是一对,一对一的关系,如果只上锁不解锁,会发生死锁 lock.acquire() print(2) lock.release() # 解锁 lock.release() import json # 读取票数,更新票数 def wr_info(sign,dic=None): if sign == "r"

Java中的锁

别来无恙 提交于 2019-12-05 02:55:31
一、乐观锁   乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据时都认为别人不会修改,所以不会上锁,但是在更新时会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写操作。   Java中的乐观锁基本是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 二、悲观锁   悲观锁就是悲观思想,即认为写多,遇到并发写的可能性高,每次去拿数据时都认为被人会修改,所以每次在读写数据时都会上锁。这样别人想读写这个数据就会block知道拿到锁。Java中的悲观所就是Synchronized,AQS框架下的锁则是先尝试CAS乐观锁去获取锁,若获取不到时,才会转换为悲观锁,如RetreenLock。 三、Synchronized同步锁 可以把任意一个非null的对象当作锁,它属于独占式的悲观锁,同时属于可重入锁。 作用范围:   1)作用于方法时,锁住的是对象的实例(this);   2)作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久代PermGen(JDK1.8则是metaspace),永久代是全局共享的,因此静态方法相当于类的一个全局锁,会锁所有调用该方法的线程。   3

java中的线程安全

馋奶兔 提交于 2019-12-04 15:08:18
在Java中,线程的安全实际上指的是内存的安全,这是由操作系统决定的。 目前主流的操作系统都是多任务的,即多个进程同时运行。为了保证安全,每个进程只能访问分配给自己的内存空间,而不能访问别的、分配给别的进程的内存空间,这一安全特性是由操作系统保障的。但是线程却与进程不同,因为在每个进程的内存空间中都会有一块特殊的公共区域,通常被称为堆(内存),这块内存区域是进程内所有的线程都可以访问得到的,这个特性是线程之间通信的一种方式,但是却会引发多个线程同时访问一块内存区域可能产生的一系列问题,这些问题被统称为线程的安全问题。 如何在Java中保证线程安全,也就是保证内存的安全,是一个重要的知识点。 使用局部变量保证线程安全(内存隔离法) 在程序中,操作系统会为每个线程分配专属的内存空间,通常被称为栈内存。栈内存是当前线程所私有的,其它线程无权访问,这是由操作系统保障的。那么,如果想要一些数据只能被某个线程访问的话,就可以把这些数据放入线程专属的栈内存中,其中最常见的就是局部变量,局部变量在线程执行方法时被分配到线程的栈内存中。 double avgScore(double[] scores) { double sum = 0; for (double score : scores) { sum += score; } int count = scores.length; double

mysql的锁机制详解

时光总嘲笑我的痴心妄想 提交于 2019-12-04 12:32:25
这段时间一直在学习 mysql 数据库。项目组一直用的是 oracle ,所以对 mysql 的了解也不深。本文主要是对 mysql 锁的总结。 Mysql 的锁主要分为 3 大类: 表级锁:存储引擎为 Myisam 。锁住整个表,特点是开销小,加锁快,锁定力度大,发生锁冲突的概率最高,并发度最低。 页级锁:存储引擎为 BDB 。锁住某一页的数据( 16kb 左右),特点:开销和枷锁时间介于表级和行级之间;会出现死锁,锁定力度介于表锁和行锁之间,并发度一般。 行级锁:存储引擎为 innodb 。锁住某一行的数据,特点:锁的实现更加复杂,开销大,加锁速度慢。 根据以上特点,仅从锁的角度来说:表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如 Web 应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理( OLTP )系统。 接下来进行行级锁的详解,行级锁主要分为以下 7 类:共享 / 排他锁、意向锁、记录锁、间隙锁、临建锁、插入意向锁、自增锁。 共享 / 排他锁: 共享锁:又称读锁,可以允许读,但不能写。共享锁可以与共享锁一起使用。 语句: select ... lock in share mode 排他锁:又称写锁,不能允许读,也不能允许写,排他锁不能与其他所一起使用。 语句: select ... for

并发编程

做~自己de王妃 提交于 2019-12-04 06:55:09
目标:让服务端能够支持高并发+高性能一、 操作系统发展史 多道技术(*****) 产生背景:想要在单核下实现并发 多道技术的核心: 1、空间上的复用(具体指的是内存中同时读入多道程序,多道程序的内存空间是物理隔离) 2、时间上的复用(复用cpu的时间) 切换+保存状态=》并发 切换: 1、遇到IO切换(可以提升效率) 2、运行时间过长或者有一个优先级更高的进程抢走了cpu(反而会降低效率) 二、进程 (参考博客: https://www.cnblogs.com/linhaifeng/articles/7428874.html ) 1、进程理论(*****) 1、进程与程序区别 2、并发与并行 并发:看起来同时运行,单核就可以实现并发,但是单核无法实现并行 并行:真正意义上的同时运行,一个cpu同一时刻只能做一件事 只有多核才能同时做多件事,即并行的效果 串行:按照固定的顺序一个个地执行 3、不同操作系统开启子进程的区别 4、一个进程的三种运行状态 2、开启进程的两种方式(*****) #方式一 from multiprocessing import Process import time def task(name): print('%s is running' %name) time.sleep(3) print('%s is done' %name) if __name__ =

C语言-线程

感情迁移 提交于 2019-12-03 08:27:45
线程c程序同时执行很多任务,与进程相比较,代码量小,执行速度快 每次执行线程函数都需要检查错误调用error函数 1.如何调用线程? 线程函数的返回类型为void * 需要pthread.h头文件支持 创建线程: pthread_t xxx; pthread_create(&xxx, NULL, 执行的函数名, NULL) 回收线程 void * xxxx; pthread_join(线程名字, &xxxx) 用来防止线程同时调用相同变量,需要建立互斥锁 创建互斥锁: pthread_mutex_t xxx=PTHREAD_MUTEX_INITIALIZER 使用互斥锁 pthread_mutex_lock(&xxx); 打开互斥锁 pthread_mutex_unlock(&xxx); 当使用了pthread.h头文件后,gcc对源码的编译需要加入-lpthread参数连接pthread库 来源: https://www.cnblogs.com/renren-study-notes/p/11784962.html

C++标准库之condition_variable(条件变量)

匿名 (未验证) 提交于 2019-12-03 00:32:02
是C++ 标准程序库中的一个头文件,定义了C++11标准中的一些用于并发编程时表示条件变量的类与方法等。 或称临界区)时,不但需要用互斥锁实现独享访问以避免并发错误(称为竞争危害),在获得互斥锁进入临界区后还需要检验特定条件是否成立: (1) 、如果不满足该条件,拥有互斥锁的线程应该释放该互斥锁,把自身阻塞(block) 并挂到(suspend)条件变量的线程队列中 (2) 、如果满足该条件,拥有互斥锁的线程在临界区内访问共享资源,在退出临界区时通知(notify) 在条件变量的线程队列中处于阻塞状态的线程,被通知的线程必须重新申请对该互斥锁加锁。 的标准库中新增加的条件变量的实现,与pthread 的实现语义完全一致。使用条件变量做并发控制时,某一时刻阻塞在一个条件变量上的各个线程应该在调用wait操作时指明同一个互斥锁,此时该条件变量与该互斥锁绑定;否则程序的行为未定义。条件变量必须与互斥锁配合使用,其理由是程序需要判定某个条件(condition或称predict)是否成立,该条件可以是任意复杂。 离开临界区的线程用notify操作解除阻塞(unblock)在条件变量上的各个线程时,按照公平性(fairness)这些线程应该有平等的获得互斥锁的机会,不应让某个线程始终难以获得互斥锁被饿死(starvation),并且比后来到临界区的其它线程更为优先(即基本上FIFO)

浅析Go中的MPG模式(二)――channel通讯

匿名 (未验证) 提交于 2019-12-03 00:09:02
首先拓展一下额外的内容: runtime包介绍 (图片来自Go语言中文网) 一些较为重要的函数介绍 func NumCPU () int 使用NumCPU方法能够获得一个本地机器的逻辑CPU个数的int类型数值 func GOMAXPROCS ( n int ) int GOMAXPROCS设置可同时执行的最大CPU数,并返回先前的设置。 若 n < 1,它就不会更改当前设置。本地机器的逻辑CPU数可通过 NumCPU 查询。本函数在调度程序优化后会去掉。 一般来说,在go1.8版本之后,系统会默认使用全部逻辑CPU进行并行操作。而在go1.8之前的版本,则需要自己设置(即使用GOMAXPROCS)。有的时候设计者需要保留一些CPU的功能占用,也会自主设定GOMAXPROCS比最大可用CPU数量少一些。 拓展完毕。接下来进入正题 那么不同的Goroutine之间如何通讯呢?有两种方式: 1、全局变量互斥锁 2、管道Channel 在Go语言中倡导: “不要以共享内存的方式来通信,相反,要通过通信来共享内存。” 首先看一下传统的并发形式: 多线程共享内存,这也是Java、C#或者C++等语言中的多线程开发的常规方法,其实golang语言也支持这种传统模式。 另外一种是Go语言特有的: CSP(Communicating Sequential Processes)并发模型