我正在使用praw从reddit获取新提交:
for submission in submissions:
print('Submission being evaluated:', submission.id)
p = Process(target = evaluate, args = (submission.id, lock))
p.start()
使用此代码时,有时会获得链接到较早提交内容的ID。 因此,我更改了脚本以检查提交的内容是否是新的:
for submission in submissions:
if ((time.time()-submission.created) < 15): #if submission is new
lock.acquire()
print('Submission being evaluated:', submission.id)
lock.release()
p = Process(target = evaluate, args = (submission.id, lock))
p.start()
else:
lock.acquire()
print("Submission "+submission.id+" was older than 15 seconds")
lock.release()
但是很长一段时间内,即使我使用先前的脚本获得了大量旧提交ID,其他部分也没有执行。
所以我的问题是,当我运行print(submission.id)
时,它在创建子流程时是否在后台运行,可能会导致问题并更改submitt.id的值,或者与第二个巧合是偶然的脚本,我没有旧的提交?
谢谢!
答案 0 :(得分:2)
要回答标题中的问题,不。
流sys.stdout
所写的 print
通常是行缓冲的(尽管在这种情况下这无关紧要,因为print
写一个换行符(除非告诉不要)),并且在线程和子进程之间共享(除非明确地不共享)。
在不了解有关此代码的更多信息的情况下,很难说更多。 (谁知道,也许您那里有一个后台线程在悄悄地更改submission.id
?)
编辑:
原始帖子中的新信息,即
print('Submission being evaluated:', submission.id)
正在打印,而不是
print(submission.id)
很关键。
print()
调用的每个参数都是原子打印的,但是如果同时有两个print()
进程(例如print('a', 'b')
)运行,则a a b b
很有可能得到{{1} },而不是a b a b
。
答案 1 :(得分:1)
这是我喜欢用来安全打印到控制台的功能。那就是Lock()的正确用法,在非常简单的操作周围使用它。我实际上是在一个类中使用它的,所以我不会像下面的示例那样传递锁对象,但是原理相同。
此外,答案可能是 是的,但是不确定性要大得多。每次读写submission.id
时是否还在使用锁?通常,如果您有一个由多个进程共享的对象,则最好做到这一点,最好也使用Value
库中的multiprocessing
类,因为值对象被设计为在两个对象之间安全地共享流程。以下是一个没有流程的琐碎但清晰的示例(那就是您的工作!)。
from multiprocessing import Process, Lock, #...
myLock = Lock()
myID = ""
def SetID(id, lock):
with lock:
id = "set with lock"
return
def SafePrint(msg, lock):
lock.acquire()
print(msg)
lock.release()
return
SetID(myID, myLock)
SafePrint(myID, myLock)