mysql锁与程序锁_GIL:全局解释器锁 VS 用户程序锁

'''GIL:全局解释器锁的来历

四核:同一时刻真正有四个任务在运行,多核的意义在于此

单核:看上去是并发的,因为进行了上下文切换,单核永远是串行的,并发是假象

CPython中不论有多少核,只有一个核心的CPU资源被使用,因为同一时间只有一个线程能拿到GIL锁。

为什么这样设计呢?CPython的线程是调用操作系统的c语言的原生线程,该线程不是线程安全的。balabalabala...

===================官方解释======================

在CPython中,全局解释器锁或GIL是一个互斥锁,

这个锁是必要的,主要是因为CPython的内存管理不是线程安全的。

(然而,由于GIL的存在,其他特征已经发展成依赖于这个锁形成的线程安全环境)

=================================================

由于GIL是全局的,所以在多线程(多核)时,线程需满足两个条件才能执行

1、被操作系统调度出来【操作系统允许它占用CPU】 2、获取到GIL锁【CPython解释器允许它执行指令】

怎样避免GIL影响性能?就是减少GIL锁对线程的影响

1、在单核机器上Python和其他语言一样,“多线程”只是是假象实际上还是单线程。第2条总能满足,性能没有影响

2、在多核机器上Python只有一个核心在使用。因为多核多线程中,同时只有一个线程申请到GIL。所以要尽量减少

对GIL的申请,例如:全IO密集型任务时才使用多线程,

避免在计算密集型任务中使用Python的多线程(因为计算需要CPU资源,会频繁申请GIL锁,造成其他线程等待)

================================================

用户程序锁:

还有一个锁,用户程序锁,跟GIL没有关系。这个锁是保证某个全局变量的修改必须是串行的

假设有全局变量num=0,线程作用是对num执行加1的操作。

在线程调度的时候,A线程获取到num=0,A执行到一半,CPU执行B线程,

B线程将num修改num=1,CPU继续执行A线程,A线程执行完毕,将num修改成1,而num在AB线程执行完其实应该为2

此时就应该对num变量加锁。这个锁就是用户程序锁,这个锁不同于GIL锁。GIL锁是同一时间只能有一个线程使用

CPU资源,要保证同一时间只有一个线程访问某块数据就需要“用户程序锁”

=====================================================

在Python2.x版本+某些操作系统里不加用户程序锁会导致结果不准。

在Python3.x版本+某些操作系统里不确定是否有同样的问题,但是最好加上。'''

importthreadingimporttime

lock=threading.Lock()classFoo:

num=0

@classmethoddefrun(cls):

time.sleep(2)

lock.acquire()

cls.num+= 1lock.release()

thread_objs=[]for i in range(20):

thread_objs.append(threading.Thread(target=Foo.run, args=()))

start_time=time.time()for i inthread_objs:

i.start()for i inthread_objs:

i.join()print(Foo.num) #20

print(time.time()-start_time) #2.0051145553588867

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值