多线程在python中修改全局列表

我想在一个线程中每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变量.
>使用锁时,应尝试尽可能限制获取和释放之间的代码.在先前的代码中,您永远不会释放锁.

上一篇:Java等待/通知实现,无需同步


下一篇:camke(4)配置sophus