首先要说明一下资源共享一般是发生在一个进程中的不同线程中,当多个线程同时访问同一个变量时容易产生共享变量的问题。
进程(Process):普通的解释就是,进程是程序的一次执行。
线程(Thread):线程可以理解为进程中的执行的一段程序片段。
那么就是说进程中包含N多个线程。可以简单理解为一个进程就是一次电脑上打开一个运行的exe文件,运行这个exe文件需要背后很多个线程来配合它完成一系列包括启动,登录,等等的操作。
进程与进程之间是独立的,这主要是表现在内存空间,上下文环境,而线程则在进程的空间内运行。对于一个进程中的多个线程来说它们之间享用共有的上下文环境,以及同一内存空间。另外同一代码中的两段代码不能同时执行(除非引入多线程)。
在python中多线程的引入在3.x与2.x的版本中不太相同,在3.X的版本中建议使thread
那么问题来了,当进行多线程操作的时候如果两个函数同时用同一个共享的变量那么容易产生输出错误的问题:
1 import threading 2 sum = 0 3 sumloop = 100000 4 lock = threading.Lock() 5 def count(): 6 global sum, sumloop 7 for i in range(sumloop): 8 sum += 1 9 def substracion(): 10 global sum, sumloop 11 for i in range(sumloop): 12 sum -= 1 13 if __name__ =="__main__": 14 print("start{0}".format(sum)) 15 t1 = threading.Thread(target = count,args = ()) 16 t2 = threading.Thread(target = substracion, args = ()) 17 # 启动多线程 18 t1.start() 19 t2.start() 20 # 启动死等 21 t1.join() 22 t2.join() 23 print("Done:{0}".format(sum))
为了解决这个问题引入一个变量锁的问题,先将全局变量在该线程中锁住使用,然后等运算完成后给它解锁让别的函数使用。其实这里的锁简单的可以理解为一个令牌。lock.acquire()的目的是为了申请一个使用的令牌,表示这个参数我已经在使用了在我用完前
其他的函数使用他时不会给他用,只有等到我的函数使用完,释放之后lock.release()其他函数才可以使用。
''' 共享变量用上锁的方式可以防止共享变量问题 ''' import threading sum = 0 sumloop = 100000 lock = threading.Lock() def count(): global sum, sumloop for i in range(sumloop): # 给变量上锁 lock.acquire() sum += 1 #lock.release() def substracion(): global sum, sumloop for i in range(sumloop): # 给变量上锁 lock.acquire() sum -= 1 lock.release() if __name__ =="__main__": print("start{0}".format(sum)) t1 = threading.Thread(target = count,args = ()) t2 = threading.Thread(target = substracion, args = ()) # 启动多线程 t1.start() t2.start() # 启动死等 t1.join() t2.join() print("Done:{0}".format(sum))