"print"函数是在新的子流程中运行还是在类似的东西中运行?



我正在使用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)创建子进程时它是否在后台运行,可能会导致问题并更改 submission.id 的值,或者只是巧合,使用第二个脚本我没有收到旧的提交?

提前感谢!

要回答标题中的问题,没有。

sys.stdoutprint写入的流通常是行缓冲的(尽管在这种情况下这无关紧要,因为print写一个换行符(除非被告知不要((,并且在线程和子进程之间共享(除非明确取消共享(。

如果不了解有关此代码的更多信息,就很难说更多。(谁知道呢,也许你在那里的某个地方有一个后台线程,偷偷地改变了submission.id

编辑

原帖子中的新信息,即

print('Submission being evaluated:', submission.id)

正在打印,而不是

print(submission.id)

至关重要。

print()调用的每个参数都是原子打印的,但如果两个进程或线程同时print(),假设print('a', 'b'),则完全有可能得到a a b b而不是a b a b

这是一个我喜欢用来安全打印到控制台的功能。这是 Lock(( 的正确用法,在非常简单的操作中使用它。我实际上在类中使用它,所以我没有像下面的示例那样传递 lock 对象,而是相同的原理。

此外,答案可能是肯定的,但它的不确定性多于确定性。您是否每次读写submission.id时都使用锁?通常,如果对象由多个进程共享,则最好执行此操作,并且最好使用multiprocessing库中的Value类,因为值对象旨在在进程之间安全共享。下面是一个没有流程的琐碎但清晰的例子(这是你的工作!

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)

相关内容

  • 没有找到相关文章

最新更新