首页 > 其他分享 >多线程共享全局变量的问题

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

时间:2023-07-29 11:44:12浏览次数:35  
标签:全局变量 变量 num 线程 共享 多线程

线程之间共享全局变量

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

问题

示例

 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()

输出:

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模型等,以降低共享状态的复杂性。

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

 

标签:全局变量,变量,num,线程,共享,多线程
From: https://www.cnblogs.com/allenxx/p/17589564.html

相关文章

  • 多线程编程
    一、线程,进程介绍线程:是操作系统中独立运行的最小单位。每个线程都有自己的执行路径、程序计数器、堆栈和一组寄存器。线程共享进程的资源,如内存和文件描述符,可以并发执行,从而提高程序的并发性和响应性。进程:是操作系统中运行的一个程序实例。它拥有独立的内存空间和系统资源,如......
  • 多线程
    多线程实现的几种方式1.继承Thread类,重写run方法。2.实现Runnable,实现run方法。3.实现Callable接口。4.实现有返回结果的线程,使用ExecutorService、Callable、Future实现返回结果的线程。附带学习地址:https://www.php.cn/faq/543054.html......
  • 实现多线程多任务的步骤
    步骤 1.导入线程模块importthreading2.创建子线程并指定执行的任务sub_thread=threading.Thread(target=任务名3.启动线程执行任务sub_thread.start() 示例1'''2在Python中,实现多线程多任务可以通过使用threading模块来创建和管理线程34最佳实践:......
  • Android多线程及异步处理问题
    1、问题提出1)为何需要多线程?2)多线程如何实现?3)多线程机制的核心是啥?4)到底有多少种实现方式?2、问题分析1)究其为啥需要多线程的本质就是异步处理,直观一点说就是不要让用户感觉到“很卡”。eg:你点击按钮下载一首歌,......
  • java多线程学习-java.util.concurrent详解
    java多线程学习-java.util.concurrent详解(一)Latch/Barrier   Java1.5提供了一个非常高效实用的多线程包:java.util.concurrent,提供了大量高级工具,可以帮助开发者编写高效、易维护、结构清晰的Java多线程程序。从这篇blog起,我将跟大家一起共同学习这些新的Java多线......
  • 关于异步多线程
    方法一:利用线程池或@Async注解使用@Async注解,可以实现多个方法并行执行,然后将它们的返回结果进行处理。@Async注解会使被标注的方法在调用时,将任务提交给一个线程池中的线程去执行,不会阻塞主线程。下面是一个简单的示例,演示如何使用@Async注解来处理多个方法的返回结果:......
  • 关于打印共享的那些事,
    今天看到一个小视频,了解到打印机共享常见连接出错问题的解决方案:注册表命令:regedit注册表目录:HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\Print新建32位值名称:RpcAuthnLevelPrivacyEnabled,值为0共享与被共享都要配置,重启还需要!重点来了,打印机共享终极解决......
  • Java并发(十三)----共享存在的问题
    1、小故事老王(操作系统)有一个功能强大的算盘(CPU),现在想把它租出去,赚一点外快小南、小女(不同的线程)来使用这个算盘来进行一些计算,并按照时间给老王支付费用但小南不能一天24小时使用算盘,他经常要小憩一会(sleep),又或是去吃饭上厕所(阻塞io操作),有时还需要一根烟,没烟时思路......
  • SpringBoot中定时任务开启多线程避免多任务堵塞
    场景SpringBoot中定时任务与异步定时任务的实现:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/117083609使用SpringBoot原生方式实现定时任务,已经开启多线程支持,以上是方式之一。除此之外还可通过如下方式。为什么SpringBoot定时任务是单线程的?查看注解@Ena......
  • 什么是PHP共享内存,用实例给你们解释一下
    什么是共享内存共享内存是一种在同一台机器的不同进程(应用程序)之间交换数据的方式。一个进程可创建一个可供其他进程访问的内存段,并赋予它相应的权限。每个内存段拥有一个惟一的ID,我们通常称之为shmid,这个ID指向一个物理内存区域,其他进程可通过此ID来操作这块内存,包扩读取、写......