python threading同一进程下线程共享全局变量

一、共享可变类型参数

        可变类型(列表、字典、可变集合)

        要共享的是可变类型参数,直接将该参数当作实参通过args传入线程中去,其中sleep函数的作用是降低运行速度,方便打印出想要的结果

import threading
from time import sleep

def demo1(a,num):
    sleep(0.5)
    #为a增加元素
    for i in range(num):
        a.append(i)
    print('demo1的a:{}'.format(a))

def demo2(a,num):
    sleep(0.5)
    #为a增加元素
    for i in range(num):
        a.append(i*2)
    print('demo2的a:{}'.format(a))

def main():
    #创建两个参数
    a=[11,22,33]
    num=8
    #创建两个线程,并将两个参数传递给指定的函数
    threading.Thread(target=demo1,args=(a,num)).start()
    threading.Thread(target=demo2, args=(a,num)).start()
    #打印线程数
    print(threading.enumerate())
    sleep(1)
    print('主线程的a:{}'.format(a))

if __name__ =='__main__':
    main()

打印结果:

可以看到最后的结果是两个线程内的计算都进行了的,即同一进程下线程是共享变量的。

二、共享不可变类型参数

         不可变类型(数字、字符串、元组、不可变集合)

         要共享的是不可变类型参数,不能直接将该参数当作实参通过args传入线程中去,需要在进程执行前创建不可变类型的参数,并且在线程中对其进行修改时需要申明全局变量。

import threading
from time import sleep

def demo1(num):
    '''a+100'''
    sleep(0.5)
    for i in range(num):
        global a
        a +=1
    print('demo1的a:{}'.format(a))
def demo2(num):
    '''a+100'''
    sleep(0.5)
    for i in range(num):
        global a
        a +=1
    print('demo2的a:{}'.format(a))

def main():
    #创建一个参数
    num=100
    #创建两个线程,并将参数传递给指定的函数
    threading.Thread(target=demo1,args=(num,)).start()
    threading.Thread(target=demo2, args=(num,)).start()
    #打印线程数
    print(threading.enumerate())
    sleep(1)
    print('主线程的a:{}'.format(a))

if __name__ =='__main__':
    #创建不可变类型的参数
    a=0
    main()

打印结果:

三、互斥锁(共享过程中碰到的问题)

        当 参数a  加100,加200时,没有碰到问题,加10000000,加两千呢?上代码,直接将num改成10000000 ,此时的运行结果:

        原因:多线程共享全局变量会出现资源竞争

        解决方法:使用互斥锁,一个线程使用锁时,另一个线程就不能对锁中的对象进行操作,直到解锁后,才能对锁中的对象进行操作。

import threading
from time import sleep

def demo1(num,mutex):
    '''对数据进行操作'''
    for i in range(num):
        global a
        #锁定
        mutex.acquire()
        #对数据进行处理
        a +=1
        #解锁
        mutex.release()
    print('demo1的a:{}'.format(a))
def demo2(num,mutex):
    '''对数据进行操作'''
    for i in range(num):
        global a
        # 锁定
        mutex.acquire()
        # 对数据进行处理
        a += 1
        # 解锁
        mutex.release()
    print('demo2的a:{}'.format(a))

def main():
    #创建一个互斥锁,默认没有上锁
    mutex=threading.Lock()
    #创建一个参数
    num=10000000
    #创建两个线程,并将参数传递给指定的函数
    threading.Thread(target=demo1,args=(num,mutex)).start()
    threading.Thread(target=demo2, args=(num,mutex)).start()
    #打印线程数
    print(threading.enumerate())
    sleep(10)
    print('主线程的a:{}'.format(a))

if __name__ =='__main__':
    #创建不可变类型的参数
    a=0
    main()

从上面可以看到其实互斥锁就是调用了一个threading下的lock函数

#创建一个互斥锁,默认没有上锁
mutex=threading.Lock()
# 锁定
mutex.acquire()
# 对数据进行处理
a += 1
# 解锁
mutex.release()

打印结果:

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值