Python多任务编程——线程间共享变量

相关标签:1.使用Python增强Web功能
2.Shodan与Python API

问题:线程间共享全局变量数据出错



import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _


运行结果:




理论上,实现了100万次循环,每次循环对全局变量加1,最终结果应为2000000。实际结果如上图所示。

原因:



两个线程同时操作全局变量。线程1读取全局变量时,线程2也在读取全局变量。对变量进行操作时,读取的是原始变量,而非操作后的变量。因为线程1对变量的操作未提交,所以线程2读取的仍是之前的变量值。
解决方案

使用进程同步,确保同一时刻只有一个线程操作数据。

1. 使用 join() 方法

import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
first.join ( ) _
second.start ( ) _
结果:



原理:程序运行时加入 first.join() 等待,第一个线程完成后第二个线程才开始运行,确保同一时刻只有一个线程操作变量。
线程同步:一个任务执行完毕后再执行另一个任务,同一时刻只有一个任务在执行。

2. 互斥锁

import threading

g_num = 0

# Creating a mutex is essentially a function via
LOCK = threading.Lock ( ) _
def task1 ():
# lock
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
# release lock
LOCK.release ( ) _


def task2 ():
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
LOCK.release ( ) _


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _

结果:





原理:对共享数据加锁,同一时刻只有一个线程进行操作,多个线程共同抢占,使用 threading 中的锁函数率先抢占成功。运行第一个线程时,先用 lock.acquire() 锁定当前线程,期间其他线程无法运行。循环结束后,使用 lock.release() 释放当前线程,之后其他线程才能操作。确保同一时刻只有一个线程在运行。
但是,互斥锁在一定程度上影响了代码的执行效率,将多任务变为单任务执行,还可能引发死锁问题(由于锁未及时释放导致)。

版权声明:本文由阿里云实名注册用户贡献,版权归作者所有。阿里云开发者社区不拥有版权,也不承担相应法律责任。具体规则请参阅《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如您发现本社区存在涉嫌抄袭的内容,请填写侵权投诉表进行举报。一经核实,本社区将立即删除涉嫌侵权内容。

相关文章

探索更多特惠

  1. 短信服务(SMS)与邮件服务

    50000封邮件包低至1.99美元,120条短信仅需1.00美元

phone 联系我们
你好,我是AI助理。
可以解答问题、推荐解决方案等。