“打印”功能是否在新的子流程中运行或类似?

时间:2018-08-16 19:54:17

标签: python multiprocessing

我正在使用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的值,或者与第二个巧合是偶然的脚本,我没有旧的提交?

谢谢!

2 个答案:

答案 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)