我想在一个线程中每2秒将一个项目添加到全局列表中,
并将列表保存到数据库中,然后每3秒在另一个线程中清空该列表.
我创建了两个局部变量来监视添加的项总数和保存的项总数,它们应该每6秒钟相等,但事实并非如此.
这是我的代码:
import datetime
import psutil,os,time
from threading import *
class AddToList(Thread):
totalAdded=0
def run(self):
lock=RLock()
lock.acquire()
while True:
entryList.append("AddToList at "+str(datetime.datetime.now()))
self.totalAdded=self.totalAdded+len(entryList)
print("totalAdded:"+str(self.totalAdded))
time.sleep(2)
lock.release()
class SaveList(Thread):
totalSaved=0
'''save entry to server'''
def __init__(self):
Thread.__init__(self)
def run(self):
lock=RLock()
lock.acquire()
while True:
#save list to database,then empty the list
self.totalSaved=self.totalSaved+len(entryList)
del entryList[:]
print("totalSaved:"+str(self.totalSaved))
time.sleep(3)
lock.release()
if __name__=="__main__":
global entryList
entryList=[]
addClass= AddToList()
addClass.start()
saveClass=SaveList()
saveClass.start()
结果:
totalAdded:2
totalSaved:2
totalAdded:3
totalSaved:3totalAdded:4
totalAdded:6
totalSaved:5
totalAdded:7
totalSaved:6
totalAdded:8
totalAdded:10
totalSaved:8
totalAdded:11
totalSaved:9
totalAdded:12
totalAdded:14
totalSaved:11
totalAdded:15
totalSaved:12
...........
...........
totalAdded:51
totalSaved:39totalAdded:52
totalAdded:54
totalSaved:41
totalAdded:55
totalSaved:42
totalAdded:56
totalAdded:58
totalSaved:44
totalAdded:59
totalSaved:45totalAdded:60
......
......
我是python的新手,并在线程,锁和RLock方面进行了大量搜索,但是没有运气.
哪里错了?
解决方法:
要使Lock和RLock正常工作,必须在每个线程中使用相同的对象.锁定对象必须具有与您要“保护”的对象相同的“可见性”.
这是应该工作的新版本代码.它还避免使用诸如全局变量之类的东西.
import datetime
import time
import threading
class AddToList(threading.Thread):
def __init__(self, lock, entryList):
threading.Thread.__init__(self)
self.totalAdded = 0
self.entryList = entryList
self.lock = lock
def run(self):
while True:
self.lock.acquire()
entryList.append("AddToList at {}".format(datetime.datetime.now()))
self.totalAdded += 1
self.lock.release()
print("totalAdded: {}".format(self.totalAdded))
time.sleep(2)
class SaveList(threading.Thread):
def __init__(self, lock, entryList):
threading.Thread.__init__(self)
self.totalSaved = 0
self.entryList = entryList
self.lock = lock
def run(self):
while True:
self.lock.acquire()
self.totalSaved += len(self.entryList)
del self.entryList[:]
self.lock.release()
print("totalSaved: {}".format(self.totalSaved))
time.sleep(3)
if __name__=="__main__":
lock=threading.Lock()
entryList=[]
addClass = AddToList(lock, entryList)
addClass.start()
saveClass = SaveList(lock, entryList)
saveClass.start()
注意事项:
>当您没有特殊需要时,请使用Lock而不是RLock. RLock慢得多.
>正如某人已经指出的,最好避免在不需要时使用全局变量.同样,仅在有意义时使用Class变量.
>使用锁时,应尝试尽可能限制获取和释放之间的代码.在先前的代码中,您永远不会释放锁.