python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁

python

ps:python解释器" title="python解释器">python解释器有很多种,最常见的就是C python解释器

GIL全局解释器锁:
    GIL本质上是一把互斥锁:将并发变成串行,牺牲效率保证了数据的安全

    用来阻止同一个进程下的多个线程的同时执行(同一个进程内多个线程无法实现并行但是可以实现并发)

    GIL的存在是因为C python解释器的内存管理不是线程安全的

    垃圾回收机制:

        1、引用计数

        2、标记清除

        3、分代回收

    研究python 的多线程是否有用的话需要分情况讨论:

        同时执行四个任务  计算密集型:10s

# 计算密集型

from multiprocessing import Process

from threading import Thread

#mport os,time

def work():

res=0

for i in range(100000000):

res*=i

if __name__ == '__main__':

l=[]

print(os.cpu_count()) # 本机为6核

start=time.time()

for i in range(6):

# p=Process(target=work) #耗时 4.732933044433594

p=Thread(target=work) #耗时 22.83087730407715

l.append(p)

p.start()

for p in l:

p.join()

stop=time.time()

print('run time is %s' %(stop-start))

        单核情况下:

            开线程更节省资源

        多核情况下:

            开进程:10s

            开线程:40s

        同时执行四个IO密集型任务

# IO密集型

from multiprocessing import Process

from threading import Thread

import threading

import os,time

def work():

time.sleep(2)

if __name__ == '__main__':

l=[]

print(os.cpu_count()) #本机为6核

start=time.time()

for i in range(4000):

p=Process(target=work) #耗时9.001083612442017s多,大部分时间耗费在创建进程上

# p=Thread(target=work) #耗时2.051966667175293s多

l.append(p)

p.start()

for p in l:

p.join()

stop=time.time()

print('run time is %s' %(stop-start))

        单核:开线程更省资源

        多核:开线程更省资源

    

Event事件:

    

from threading import Event,Thread

import time

# 先生成一个event对象

e = Event()

def light():

print('红灯正亮着')

time.sleep(3)

e.set() # 发信号

print('绿灯亮了')

def car(name):

print('%s正在等红灯'%name)

e.wait() # 等待信号

print('%s加油门飙车了'%name)

t = Thread(target=light)

t.start()

for i in range(10):

t = Thread(target=car,args=('伞兵%s'%i,))

t.start()

信号量:在不同的领域中,对应不同的知识点

    互斥锁:一个厕所(一个坑)
    信号量:公共厕所(多个坑位)

from threading import Semaphore,Thread

import time

import random

sm = Semaphore(5) # 造了一个含有五个的坑位的公共厕所

def task(name):

sm.acquire()

print('%s占了一个坑位'%name)

time.sleep(random.randint(1,3))

sm.release()

for i in range(40):

t = Thread(target=task,args=(i,))

t.start()

  

死锁:

    RLock可以被第一个抢到锁的人连续的acquire和release

    每acquire一次锁身上的计数就加1

    每release一次锁身上的计数就减1

    只要是锁的计数不为0 其他人都不能抢

class MyThread(Thread):

def run(self): # 创建线程自动触发run方法 run方法内调用func1 func2相当于也是自动触发

self.func1()

self.func2()

def func1(self):

mutexA.acquire()

print('%s抢到了A锁'%self.name) # self.name等价于current_thread().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(10):

t = MyThread()

t.start()

递归锁:

import threading

class MyThread(threading.Thread):

def run(self):

global n1, n2

lock.acquire() # 加锁

n1 += 1

print(self.name + ' set n1 to ' + str(n1))

lock.acquire() # 再次加锁

n2 += n1

print(self.name + ' set n2 to ' + str(n2))

lock.release()

lock.release()

n1, n2 = 0, 0

lock = threading.RLock()

if __name__ == '__main__':

thread_list = []

for i in range(5):

t = MyThread()

t.start()

thread_list.append(t)

for t in thread_list:

t.join()

print('final num:%d ,%d' % (n1, n2))

以上是 python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁 的全部内容, 来源链接: utcz.com/z/389516.html

回到顶部