多线程——GIL\信号量\递归锁

互斥锁

1、什么是GIL(global interpreter lock)?
GIL是一个互斥锁:保证数据的安全(牺牲效率来获取数据的安全),阻止同一个进程内的多线=线程同时执行(不能并行但是能实现并发)
2、为什么会有GIL?
由于cpython解释器的内存管理不是线程安全的(垃圾回收机制的存在)
同一进程想的多线程不能实现并行但是可以实现并发,不同进程下可以实现并行

问题:Python多线程是不是就没有用:

举个例子:
四个任务:计算密集任务,每个任务10s
单核情况下:
		多线程好点,消耗资源少,速度快
多核情况下:
		开四个进程,10s多点
		开四个线程,40s多点

四个任务:IO密集任务,每个任务10s
单核情况下:
		多线程好点
多核情况下:
		多线程好点

总结:多线程和多进程都有自己的优点和缺点,根据项目需求合理选择
对于不同的数据要加不同的锁进行,GIL不能保证数据的安全,他只针对线程。保证同一个进程下的多个线程是安全的

3、死锁和递归锁

自定义锁(Lock):自定义锁必须一次acquire 必须对应一次release,不能连续需acquire
递归锁(RLock):可以连续acquire,每acquire一次,计数加1:针对的是第一抢到的人

from threading import Thread,Lock,RLock
import time

"""
自定义锁一次acquire必须对应一次release,不能连续acquire
递归锁可以连续的acquire,每acquire一次计数加一:针对的是第一个抢到我的人
"""
import random
#
# mutexA = Lock()
# mutexB = Lock()
mutexA = mutexB = RLock()  # 抢锁之后会有一个计数 抢一次计数加一 针对的是第一个抢到我的人

class MyThead(Thread):
    def run(self):
        self.func1()
        self.func2()

    def func1(self):
        mutexA.acquire()
        print(‘%s 抢到A锁了‘%self.name)
        mutexB.acquire()
        print(‘%s 抢到B锁了‘ % self.name)
        mutexB.release()
        print(‘%s 释放了B锁‘%self.name)
        mutexA.release()
        print(‘%s 释放了A锁‘%self.name)

    def func2(self):
        mutexB.acquire()
        print(‘%s 抢到了B锁‘%self.name)
        time.sleep(1)
        mutexA.acquire()
        print(‘%s 抢到A锁了‘ % self.name)
        mutexA.release()
        print(‘%s 释放了A锁‘ % self.name)
        mutexB.release()
        print(‘%s 释放了B锁‘ % self.name)

for i in range(100):
    t = MyThead()
    t.start()

4、信号量

sm = Semaphore()

from threading import Thread,Semaphore
import time
import random
sm = Semaphore(5)  # 五个厕所五把锁
# 跟你普通的互斥锁区别在于,普通的互斥锁是独立卫生间,所有人抢一把锁
# 信号量 公共卫生间 有多个坑,所有人抢多把锁

def task(name):
    sm.acquire()
    print(‘%s正在蹲坑‘%name)
    # 模拟蹲坑耗时
    time.sleep(random.randint(1,5))
    sm.release()

if __name__ == ‘__main__‘:
    for i in range(20):
        t = Thread(target=task,args=(‘伞兵%s号‘%i,))
        t.start()

5、线程queue:

queue分为三类:1.普通q:q=queue.Queue(3)2.先进后出:q = queue.LifoQueue(5)3.优先级q:q = queue.PriorityQueue()
#普通q
# q=queue.Queue(3)
# q.put(1)
# q.put(2)
# q.put(3)
# print(q.get())
# print(q.get())
# print(q.get())

# 先进后出q
# q = queue.LifoQueue(5)
# q.put(1)
# q.put(2)
# q.put(3)
# q.put(4)
# print(q.get())

# 优先级q
# q = queue.PriorityQueue()
# q.put((10,‘a‘))
# q.put((-1,‘b‘))
# q.put((100,‘c‘))
# print(q.get())
# print(q.get())
# print(q.get())

  



原文地址:https://www.cnblogs.com/king-home/p/10832307.html

时间: 2024-11-07 23:21:35

多线程——GIL\信号量\递归锁的相关文章

python 并发编程 多线程 GIL全局解释器锁基本概念

首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. >有名的编译器例如GCC,INTEL C++,Visual C++等.Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行. 像其中的JPython就没有GIL.然而因为CPython是大部分环境下默认的Python执行环境.所以在很多人的概

python GIL全局解释器锁与互斥锁 目录

python 并发编程 多线程 GIL全局解释器锁基本概念 原文地址:https://www.cnblogs.com/mingerlcm/p/11063837.html

python学习第37天GIL锁、死锁现象与递归锁、信号量、Event时间、线程queue

一.GIL锁 1. 什么是GIL全局解释器锁 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe

Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池

目录 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 2.死锁现象与递归锁 2.1死锁现象 2.2递归锁 3.信号量 4.GIL全局解释器锁 4.1背景 4.2为什么加锁 5.GIL与Lock锁的区别 6.验证计算密集型IO密集型的效率 6.1 IO密集型 6.2 计算密集型 7.多线程实现socket通信 7.1服务端 7.2客户端 8.进程池,线程池 Python并发编程05/ 死锁/递归锁/信号量/GIL锁/进程池/线程池 1.昨日回顾 #生产者消

线程同步锁、死锁、递归锁、信号量、GIL

目录 线程同步锁.死锁.递归锁.信号量.GIL 一.同步锁 二.死锁 三.递归锁(Rlock) 四.信号量(Semphare) 五.GIL(全局解释器锁) io密集型 计算密集型 线程同步锁.死锁.递归锁.信号量.GIL 一.同步锁 所有线程同一时间读写同一个数据,有的线程已经对数据进行修改了,造成有的线程拿到的数据时旧的数据,而不是修改后的数据,造成结果不正确,于是引入了同步锁解决问题, 同步锁的原理是同一时间只能有一个线程读写数据. 锁通常被用来实现对共享资源的同步访问.从threading

python并发编程之多线程2------------死锁与递归锁,信号量等

一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程, 如下就是死锁 1 死锁------------------- 2 from threading import Thread,Lock,RLock 3 import time 4 mutexA = Lock() 5 mutexB = Lock() 6

有关多线程(同步锁,递归锁,同步对象,信号量)

上面一个随笔已经简单介绍了多线程,比如下面在举个简单的例子: 1 #!/usr/bin/env python 2 #-*-coding:utf-8 -*- 3 4 import threading 5 import time 6 7 def add(): 8 sum = 0 9 10 for i in range(1000000): 11 sum += i 12 13 print("sum: ",sum) 14 15 16 def mul(): 17 sum2 = 1 18 for i

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q

TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务端实现并发 1.将连接循环和通信循环拆分成不同的函数 2.将通信循环做成多线程 ''' # 服务端 import socket from threading import Thread ''' 服务端 要有固定的IP和PORT 24小时不间断提供服务 能够支持并发 ''' server = sock

python全栈开发基础【第二十五篇】死锁,递归锁,信号量,Event事件,线程Queue

一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程, 如下就是死锁 #死锁现象 死锁------------------- from threading import Thread,Lock,RLock import time mutexA = Lock() mutexB = Lock() class