线程之间共享全局变量
多个线程都是在同一个进程中 , 多个线程使用的资源都是同一个进程中的资源 , 因此多线程间是共享全局变量
问题
示例
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个线程执行结果错误。就是因为资源共享存在可见性、非原子性等问题导致
在多线程环境下,共享变量可能会出现以下问题:
-
竞态条件(Race Condition):当多个线程同时访问和修改同一个共享变量时,由于执行顺序的不确定性,可能导致变量值不一致或出现错误的结果。这是因为线程之间的执行是并发的,无法确定哪个线程先执行哪个操作。
-
数据不一致性(Inconsistent Data):如果一个线程正在修改共享变量的值,而另一个线程正在读取该变量的值,那么读取到的值可能是过期的、部分修改的或者处于不一致的状态。
-
死锁(Deadlock):当多个线程同时竞争多个共享资源,并且每个线程都在等待其他线程释放资源时,可能发生死锁。这种情况下,所有线程都被阻塞,无法继续执行。
-
饥饿(Starvation):某些线程可能因为被其他线程持续抢占资源而无法获得执行的机会,导致饥饿现象发生。
-
并发冲突(Concurrency Conflict):当多个线程同时对共享变量进行写操作时,可能引发并发冲突,导致数据损坏或丢失。
为了解决这些问题,可以采取以下措施:
- 使用同步机制,如锁(Lock)、互斥量(Mutex)或信号量(Semaphore),来保证多个线程对共享变量的访问是有序和互斥的。
- 使用线程安全的数据结构,如线程安全的队列(Queue)或线程安全的字典(Dict),来避免竞态条件和数据不一致性问题。
- 避免共享状态,尽量使用局部变量或将数据进行分割,减少对共享变量的需求。
- 考虑使用更高级的并发模型,如进程间通信(IPC)或使用Actor模型等,以降低共享状态的复杂性。
需要注意的是,在使用多线程编程时,必须谨慎处理共享变量,确保线程之间的同步和互斥操作,以避免出现以上问题。
标签:全局变量,变量,num,线程,共享,多线程 From: https://www.cnblogs.com/allenxx/p/17589564.html