1. 全局解释器锁,保证同一时间只有一个线程在执行,但是由于它是把数据copy成了两份,所以

只有全局解释器锁的时候,数据加减照样出错了。

2.用户态的锁,保证同一时间,只有一个线程在真真正正地修改数据。

修改数据之前,先加一把锁。修改完了以后,释放锁。修改数据的时候,把程序变成串行的。

#主线程启动子线程之后,两者是并行的,相互之间是独立的。
import threading,time def run(n):
lock.acquire() #获取一把锁
global num #把num声明成全局变量以后,才能够进行修改。
num+=1
time.sleep(1)
lock.release() #释放锁 lock=threading.Lock() #生产一个锁的实例
num=0 #全局变量
t_objs=[]
start_time=time.time() for i in range(10):
t=threading.Thread(target=run,args=("t-%s"%i,))
t.start()
t_objs.append(t)
for t in t_objs:
t.join() #所有线程都执行完毕 print('----All threads has finished',threading.current_thread(),threading.active_count())
print('num:',num)
print('Cost time:',time.time()-start_time)

运行结果:发现确实花费了10s多。

----All threads has finished <_MainThread(MainThread, started 9908)> 1
num: 10
Cost time: 10.003000259399414 Process finished with exit code 0

3. 递归锁(又叫互斥锁),因为有多把锁,找不到出去的锁,会陷入死循环。说白了就是在一个大锁中还要再包含子锁

locks={
door1:key1,
door2:key2,
}

程序摘抄自老师的博客:

import threading,time

def run1():

    print("grab the first part data")

    lock.acquire()

    global num

    num +=1

    lock.release()

    return num

def run2():

    print("grab the second part data")

    lock.acquire()

    global  num2

    num2+=1

    lock.release()

    return num2

def run3():

    lock.acquire()

    res = run1()

    print('--------between run1 and run2-----')

    res2 = run2()

    lock.release()

    print(res,res2)

if __name__ == '__main__':

    num,num2 = 0,0

    lock = threading.RLock()

    for i in range(10):

        t = threading.Thread(target=run3)

        t.start()

while threading.active_count() != 1:

    print(threading.active_count())

else:

    print('----all threads done---')

    print(num,num2)

4.信号量Semaphore

互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。最多同时有3个在执行,当有1个执行完了的时候,就会又放1个进去。发现程序是5个5个一组进行执行。

import threading, time

def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" % n)
semaphore.release() if __name__ == '__main__': semaphore = threading.BoundedSemaphore(5) # 生成一个信号量的实例,并且定义最多允许5个线程同时运行 for i in range(20):
t = threading.Thread(target=run, args=(i,))
t.start() while threading.active_count() != 1:
pass # print threading.active_count()
else:
print('----all threads done---')

锁-lock,信号量4的更多相关文章

  1. Python进阶(3)_进程与线程中的lock(线程中互斥锁、递归锁、信号量、Event对象、队列queue)

    1.同步锁 (Lock) 当全局资源(counter)被抢占的情况,问题产生的原因就是没有控制多个线程对同一资源的访问,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为“线程不安全”.在开发过 ...

  2. python多线程编程—同步原语入门(锁Lock、信号量(Bounded)Semaphore)

    摘录python核心编程 一般的,多线程代码中,总有一些特定的函数或者代码块不希望(或不应该)被多个线程同时执行(比如两个线程运行的顺序发生变化,就可能造成代码的执行轨迹或者行为不相同,或者产生不一致 ...

  3. 并发、并行、同步、异步、全局解释锁GIL、同步锁Lock、死锁、递归锁、同步对象/条件、信号量、队列、生产者消费者、多进程模块、进程的调用、Process类、

    并发:是指系统具有处理多个任务/动作的能力. 并行:是指系统具有同时处理多个任务/动作的能力. 并行是并发的子集. 同步:当进程执行到一个IO(等待外部数据)的时候. 异步:当进程执行到一个IO不等到 ...

  4. 互斥锁lock、信号量semaphore、事件Event、

    1.互斥锁lock 应用在多进程中互斥所lock:互斥锁是进程间的get_ticket互相排斥进程之间,谁先枪占到资源,谁就先上锁,等到解锁之后,下一个进程在继续使用.# 语法: 上锁: lock.a ...

  5. 进程Process之join、daemon(守护)、terminate(关闭)、multiprocessing之锁、信号量和事件

    一.Process 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'a',) ...

  6. 漫画|Linux 并发、竞态、互斥锁、自旋锁、信号量都是什么鬼?(转)

    知乎链接:https://zhuanlan.zhihu.com/p/57354304 1. 锁的由来? 学习linux的时候,肯定会遇到各种和锁相关的知识,有时候自己学好了一点,感觉半桶水的自己已经可 ...

  7. day 7-6 GIL,死锁,递归锁与信号量,Event,queue,

    摘要: 1.死锁与递归锁 2.信号量 3.Event 4.Timer 5.GIL 6.Queue 7.什么时候该用多线程和多进程 一. 死锁与递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过 ...

  8. python之网络编程--锁、信号量、线程、队列

    一.线程,可以发现顺序执行比开线程执行时间要短.原因是,一个进程中的多线程处理,由于存在GIL,并且GIL中只能存在一个线程,加上线程又存在切换的问题,所以时间耗得多.想要解决这个问题,是开几个进程, ...

  9. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

随机推荐

  1. spark 执行架构

    术语定义 Application:Spark Application的概念和Hadoop MapReduce中的类似,指的是用户编写的Spark应用程序,包含了一个Driver 功能的代码和分布在集群 ...

  2. Python :编写条件分支代码的技巧

    『Python 工匠』是什么? 我一直觉得编程某种意义是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目. 在雕琢代码的过程中,有大工程:比如应该用什么架构.哪种设计模式.也有 ...

  3. Linux命令应用大词典-第45章 服务器配置

    45.1 ssh-agent:存储用于公钥验证的私钥 45.2 ssh-add:添加RSA或DSA身份的认证代理 45.3 ssh-keyscan:收集主机公钥 45.4 sshd:运行sshd守护进 ...

  4. 【form】 表单组件说明

    form表单组件 1)将form组件内的用户输入的<switch/> <input/> <checkbox/> <slider/> <radio/ ...

  5. a链接传参的方法

    //获取分案编号 var hrefVal=window.location.href.split("?")[1]; //得到id=楼主 //console.log(hrefVal+& ...

  6. 245. Subtree【LintCode java】

    Description You have two very large binary trees: T1, with millions of nodes, and T2, with hundreds ...

  7. 洪水!(Flooded! ACM/ICPC World Final 1999,UVa815)

    题目描述:竞赛入门经典的习题4-10 解题思路:1.把各个网格想象成一个数组 2.排序 3.雨水总体积去铺满 //太懒了只写了求海拔 #include <stdio.h> #define ...

  8. Maven编译Java项目

    Spring在线参考文档: http://spring.io/guides/gs/maven/ 下载安装 Downloadand unzip the source repository for thi ...

  9. Windows环境下使用kafka单机模式

    测试运行环境 Win10 kafka_2.11-1.0.0 zookeeper-3.4.10 1.安装Zookeeper Kafka的运行依赖于Zookeeper,所以在运行Kafka之前我们需要安装 ...

  10. CDH问题集

    1.在CM中添加主机报JDK错误 手动在机器上安装oracle-jdk1.7+update64.然后在CM中选择不安装oracle-jdk即可. 2.HostMoinitor无法与server联系 查 ...