前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 变量锁_python字符串前面加b

python 变量锁_python字符串前面加b

作者头像
全栈程序员站长
发布2022-10-04 15:20:51
7710
发布2022-10-04 15:20:51
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

一、全局解释器锁(GIL)

1、什么是全局解释器锁

在同一个进程中只要有一个线程获取了全局解释器(cpu)的使用权限,那么其他的线程就必须等待该线程的全局解释器(cpu)使用权消失后才能使用全局解释器(cpu),即时多个线程直接不会相互影响在同一个进程下也只有一个线程使用cpu,这样的机制称为全局解释器锁(GIL)。

2、全局解释器锁的好处

1、避免了大量的加锁解锁的好处

2、使数据更加安全,解决多线程间的数据完整性和状态同步

3、全局解释器的缺点

多核处理器退化成单核处理器,只能并发不能并行。

同一时刻的某个进程下的某个线程只能被一个cpu所处理,所以在GIL锁下的线程只能被并发,不能被并行。

实例:

importtimeimportthreadingdefsub():globalnum

num-= 1time.sleep(1)

num= 100 #定义一个全局变量

l = [] #定义一个空列表,用来存放所有的列表

for i in range(100): #for循环100次

t = threading.Thread(target=sub) #每次循环开启一个线程

t.start() #开启线程

l.append(t) #将线程加入列表l

for i inl:

i.join()#这里加上join保证所有的线程结束后才运行下面的代码

print(num)#输出结果为0

二、同步锁

1、什么是同步锁?

同一时刻的一个进程下的一个线程只能使用一个cpu,要确保这个线程下的程序在一段时间内被cpu执,那么就要用到同步锁。

2、为什么用同步锁?

因为有可能当一个线程在使用cpu时,该线程下的程序可能会遇到io操作,那么cpu就会切到别的线程上去,这样就有可能会影响到该程  序结果的完整性。

3、怎么使用同步锁?

只需要在对公共数据的操作前后加上上锁和释放锁的操作即可。

4、实例:

importtimeimportthreading

R=threading.Lock()defsub():globalnum

R.acquire()#加锁,保证同一时刻只有一个线程可以修改数据

num -= 1R.release()#修改完成就可以解锁

time.sleep(1)

num= 100 #定义一个全局变量

l = [] #定义一个空列表,用来存放所有的列表

for i in range(100): #for循环100次

t = threading.Thread(target=sub) #每次循环开启一个线程

t.start() #开启线程

l.append(t) #将线程加入列表l

for i inl:

i.join()#这里加上join保证所有的线程结束后才运行下面的代码

print(num)#输出结果为0

5、扩展知识

1、GIL的作用:多线程情况下必须存在资源的竞争,GIL是为了保证在解释器级别的线程唯一使用共享资源(cpu)。

2、同步锁的作用:为了保证解释器级别下的自己编写的程序唯一使用共享资源产生了同步锁。

三、递归锁和死锁

1、什么是死锁?

指两个或两个以上的线程或进程在执行程序的过程中,因争夺资源而相互等待的一个现象

importtimeimportthreading

A=threading.Lock()

B=threading.Lock()importthreadingclassobj(threading.Thread):def __init__(self):

super().__init__()defrun(self):

self.a()#如果两个锁同时被多个线程运行,就会出现死锁现象

self.b()defa(self):

A.acquire()print(‘123’)

B.acquire()print(456)

time.sleep(1)

B.release()print(‘qweqwe’)

A.release()defb(self):

B.acquire()print(‘asdfaaa’)

A.acquire()print(‘(⊙o⊙)哦(⊙v⊙)嗯’)

A.release()

B.release()for i in range(2): #循环两次,运行四个线程,第一个线程成功处理完数据,第二个和第三个就会出现死锁

t =obj()

t.start()

程序会出现阻塞现象

2、什么是递归锁?

在Python中为了支持同一个线程中多次请求同一资源,Python提供了可重入锁。这个RLock内部维护着一个Lock和一个counter

变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获

得资源。

importtimeimportthreading

A= threading.RLock() #这里设置锁为递归锁

importthreadingclassobj(threading.Thread):def __init__(self):

super().__init__()defrun(self):

self.a()

self.b()def a(self): #递归锁,就是将多个锁的钥匙放到一起,要拿就全拿,要么一个都拿不到

#以实现锁

A.acquire()print(‘123’)print(456)

time.sleep(1)print(‘qweqwe’)

A.release()defb(self):

A.acquire()print(‘asdfaaa’)print(‘(⊙o⊙)哦(⊙v⊙)嗯’)

A.release()for i in range(2):

t=obj()

t.start()

四、信号量(semaphore)

1、什么是信号量?

同进程的一样,semaphore管理一个内置的计数器,每当调用acquire()时内置函数-1,每当调用release()时内置函数+1。

计数器不能为0,当计数器为0时acquire()将阻塞线程,直到其他线程调用release()。

importthreadingimporttime

mysf= threading.Semaphore(5) #创建信号量对象,(5表示这个锁同时支持的个数)

deffunc():if mysf.acquire(): #因为使用了信号量,下面的输出就会5个5个的同时输出

print(threading.currentThread().getName() + ‘get semaphore’)

time.sleep(1)

mysf.release()for i in range(20):

t= threading.Thread(target=func)

t.start()

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/196509.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月6日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档