如何在Python多进程中防止值重叠

2024-10-03 21:28:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试Python多处理,我想使用Lock来避免变量'es'u id'值重叠。在

理论和实例表明,当一个进程调用lock时,由于另一个进程不能访问它,es_id不能重叠,但结果表明es_id常常重叠。在

id值如何不重叠?在

我的部分代码是:

def saveDB(imgName, imgType, imgStar, imgPull, imgTag, lock): #lock=Lock() in main
    imgName=NameFormat(imgName) #name/subname > name:subname
    i=0
    while i < len(imgName):
        lock.acquire()  #since global es_id
        global es_id

        print "getIMG.pt:save information about %s"%(imgName[i])
        cmd="curl -XPUT http://localhost:9200/kimhk/imgName/"+str(es_id)+" -d '{" +\
                        '"image_name":"'+imgName[i]+'", '+\
                        '"image_type":"'+imgType[i]+'", '+\
                        '"image_star":"'+imgStar[i]+'", '+\
                        '"image_pull":"'+imgPull[i]+'", '+\
                        '"image_Tag":"'+",".join(imgTag[i])+'"'+\
                        "}'"
        try:
                subprocess.call(cmd,shell=True)
        except subprocess.CalledProcessError as e:
                print e.output
        i+=1
        es_id+=1
        lock.release()

。。。在

^{pr2}$

执行结果屏幕:

image showing duplicate eids

结果是输出subprocess.call(cmd,shell=True)。我使用XPUT向ElasticSearch添加数据,es_id是数据的id。我希望这些id按顺序增加而不重叠。(因为如果它们重叠,将被以前的数据覆盖)

我知道XPOST不需要使用锁码,因为它会自动生成一个ID,但是将来我需要按顺序访问所有数据(比如读取一行文件)。在

如果您知道如何在使用XPOST后按顺序访问所有数据,您能告诉我吗?在


Tags: 数据nameimagecmdidlockes进程
2条回答

你只给出了部分代码,所以我只能看到一个潜在的问题。锁保护对es_id的访问没有任何好处。您必须锁定保护它们,无论它们出现在程序中的任何位置。为此,最好创建一个访问函数,例如:

def increment_es_id():
    global es_id
    lock.acquire()
    es_id += 1
    lock.release()

这可以从任何线程安全地调用。在

在您的代码中,最好将获取/释放调用尽可能靠近它们。这里只需要保护一个变量,这样就可以将acquire/release对移到es_id += 1语句之前和之后。。在

更好的方法是在上下文管理器中使用锁(尽管在这个简单的例子中它不会有任何区别):

^{pr2}$

看起来您正在尝试使用锁访问全局变量,但全局变量在进程之间是不同的实例。您需要使用的是共享内存值。这是一个有效的例子。它已经在Python 2.7和3.6上进行了测试:

from __future__ import print_function
import multiprocessing as mp

def process(counter):
    # Increment the counter 3 times.
    # Hold the counter's lock for read/modify/write operations.
    # Keep holding it so the value doesn't change before printing,
    # and keep prints from multiple processes from trying to write
    # to a line at the same time.
    for _ in range(3):
        with counter.get_lock():
            counter.value += 1
            print(mp.current_process().name,counter.value)

def main():
    counter = mp.Value('i') # shared integer
    processes = [mp.Process(target=process,args=(counter,)) for i in range(3)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()

if __name__ == '__main__':
    main()

输出:

^{pr2}$

相关问题 更多 >