python中全局变量_python进阶之多线程对同一个全局变量的处理方法

通常情况下:

from threading import Thread

global_num = 0

def func1():

global global_num

for i in range(1000000):

global_num += 1

print('---------func1:global_num=%s--------'%global_num)

def func2():

global global_num

for i in range(1000000):

global_num += 1

print('--------fun2:global_num=%s'%global_num)

print('global_num=%s'%global_num)

lock = Lock()

t1 = Thread(target=func1)

t1.start()

t2 = Thread(target=func2)

t2.start()

输出结果:

global_num=0

---------func1:global_num=1492752--------

--------fun2:global_num=1515462

#由于多线程不像多进程一样,每一个进程都一个独立的资源块,线程之间是共享主线程的一个资源块(虽然这样说不合适)

#这样虽然方便了线程之间的数据传递,但是又会由于线程之间执行顺序的不确定,导致最后的结果不是应该输出的正确结果。

#例如下面的例程,如果没有添加global_flag标志全局变量,就会出现,虽然逻辑上最后的结果是2000000(之所以选择这么大的一个数,是因为可以更明显的看出#这个问题),

#但是实际上并不是这个结果,而是一个小于2000000的结果,但是不排出偶然会出现2000000,这是一个极为理想的结果,这是为什么呢?

#主要还是由于线程被cpu调用的顺序不确定。具体来讲就是当主线程创建出两个子线程,分别是t1和t2,他们有分别指向func1()和func2()。

#在这两个线程中的函数中,都有一句“global_num += 1”,在计算机内部cpu执行时,这一条语句实际上是两个过程:第一个过程是从内存中读取global_num的值,完成加一操作,这个时候global_num的值还是原来的值;第二个过程是将求和的值付给global_num,这时候global_num的值才会更新。在程序执行过程中会出现这种

#情况:当cpu在执行线程t1中的语句到求和那条语句时,在执行完第一个过程停了下来,将线程t1抛出,转而执行线程t2,当线程执行一段时间后也出现这中情况

#有转而执行线程t1,这时,正好执行求和语句的第二个过程,完成最初的赋值,那么这一段时间内的整个求和就等于没做,所以出现这中最后结果不是2000000的##情况

#解决这种情况可以利用添加一个变量,利用“轮询”的方式执行,但是这样做的效率很低,而且还浪费cpu,所以一般采用“通知”方式来做。

轮询方式:

from threading import Thread

global_num = 0

global_flag = 0

def func1():

global global_num

global global_flag

if global_flag == 0:

for i in range(1000000):

global_num += 1

global_flag = 1

print('---------func1:global_num=%s--------'%global_num)

def func2():

global global_num

while True:

if global_flag != 0:

for i in range(1000000):

global_num += 1

break

print('--------fun2:global_num=%s'%global_num)

print('global_num=%s'%global_num)

t1 = Thread(target=func1)

t1.start()

t2 = Thread(target=func2)

t2.start()

运行结果:

global_num=0

---------func1:global_num=1000000--------

--------fun2:global_num=2000000

通知方式:

from threading import Thread,Lock

global_num = 0

def func1():

global global_num

for i in range(1000000):

lock.acquire()#两个线程会最开始抢这个锁,拿到锁就会处于关锁,执行后面的程序,其他线程执行处于监听状态,等待这个线程开锁,再抢锁

global_num += 1

lock.release()

print('---------func1:global_num=%s--------'%global_num)

def func2():

global global_num

for i in range(1000000):

lock.acquire()

global_num += 1

lock.release()

print('--------fun2:global_num=%s'%global_num)

print('global_num=%s'%global_num)

lock = Lock()

t1 = Thread(target=func1)

t1.start()

t2 = Thread(target=func2)

t2.start()

输出结果:

global_num=0

---------func1:global_num=1901175--------

--------fun2:global_num=2000000

以上这篇python进阶之多线程对同一个全局变量的处理方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

本文标题: python进阶之多线程对同一个全局变量的处理方法

本文地址: http://www.cppcns.com/jiaoben/python/244061.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值