多线程共享全局变量的问题

线程之间共享全局变量

多个线程都是在同一个进程中 , 多个线程使用的资源都是同一个进程中的资源 , 因此多线程间是共享全局变量

问题

示例

复制代码
 1 import threading
 2 
 3 
 4 # 全局变量
 5 g_num = 0
 6 
 7 
 8 # 对g_num进行加操作
 9 def sum_num1():
10     for i in range(1000000):
11         global g_num
12         g_num += 1
13 
14     print("g_num1:", g_num)
15 
16 
17 # 对g_num进行加操作
18 def sum_num2():
19     for i in range(1000000):
20         global g_num
21         g_num += 1
22 
23     print("g_num2:", g_num)
24 
25 
26 if __name__ == '__main__':
27     # 创建子线程
28     sum1_thread = threading.Thread(target=sum_num1)
29     sum2_thread = threading.Thread(target=sum_num2)
30 
31     # 启动线程
32     sum1_thread.start()
33     sum2_thread.start()
复制代码

输出:

1
2
g_num1: 1891306
g_num2: 2000000

定义两个函数,实现循环100万次,每循环一次给全局变量加1

创建两个子线程执行对应的两个函数,从结果中可以发现有1个线程执行结果错误。就是因为资源共享存在可见性、非原子性等问题导致

 

在多线程环境下,共享变量可能会出现以下问题:

  1. 竞态条件(Race Condition):当多个线程同时访问和修改同一个共享变量时,由于执行顺序的不确定性,可能导致变量值不一致或出现错误的结果。这是因为线程之间的执行是并发的,无法确定哪个线程先执行哪个操作。

  2. 数据不一致性(Inconsistent Data):如果一个线程正在修改共享变量的值,而另一个线程正在读取该变量的值,那么读取到的值可能是过期的、部分修改的或者处于不一致的状态。

  3. 死锁(Deadlock):当多个线程同时竞争多个共享资源,并且每个线程都在等待其他线程释放资源时,可能发生死锁。这种情况下,所有线程都被阻塞,无法继续执行。

  4. 饥饿(Starvation):某些线程可能因为被其他线程持续抢占资源而无法获得执行的机会,导致饥饿现象发生。

  5. 并发冲突(Concurrency Conflict):当多个线程同时对共享变量进行写操作时,可能引发并发冲突,导致数据损坏或丢失。

为了解决这些问题,可以采取以下措施:

  • 使用同步机制,如锁(Lock)、互斥量(Mutex)或信号量(Semaphore),来保证多个线程对共享变量的访问是有序和互斥的。
  • 使用线程安全的数据结构,如线程安全的队列(Queue)或线程安全的字典(Dict),来避免竞态条件和数据不一致性问题。
  • 避免共享状态,尽量使用局部变量或将数据进行分割,减少对共享变量的需求。
  • 考虑使用更高级的并发模型,如进程间通信(IPC)或使用Actor模型等,以降低共享状态的复杂性。

需要注意的是,在使用多线程编程时,必须谨慎处理共享变量,确保线程之间的同步和互斥操作,以避免出现以上问题。

 

posted @   Allen_Hao  阅读(606)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
点击右上角即可分享
微信分享提示