python - 属性错误: Can't pickle local object 'computation.。使用多处理队列的 function1

标签 python queue multiprocessing scheduler schedule

我有以下使用调度程序和多处理模块的代码:

def computation():
    def function1(q):
        while True:
            daydate = datetime.now()
            number = random.randrange(1, 215)
            print('Sent to function2: ({}, {})'.format(daydate, number))
            q.put((daydate, number))
            time.sleep(2)

    def function2(q):
        while True:
            date, number = q.get()
            print("Recevied values from function1: ({}, {})".format(date, number))
            time.sleep(2)

    if __name__ == "__main__":
        q = Queue()
        a = Process(target=function1, args=(q,))
        a.start()
        b = Process(target=function2, args=(q,))
        b.start()
        a.join()
        b.join()

schedule.every().monday.at("08:45").do(computation)
schedule.every().tuesday.at("08:45").do(computation)

while True:
    schedule.run_pending()
    time.sleep(1)

但是在执行代码时出现以下错误:

AttributeError: Can't pickle local object 'computation.. function1

还有:

OSError: [WinError 87] The parameter is incorrect

如何解决这个问题?我尝试通过在模块的顶层定义一个函数来解决这个问题,如文档( https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled )中所述,但它仍然给出相同的错误。

最佳答案

嵌套函数不是在顶层定义的函数,因此这就是您收到错误的原因。您需要将 function1function2 的定义重新定位到外部 的计算。

您是如何编写的,您的进程将立即启动,而不是在您安排它们运行的​​日期开始。这可能符合您的预期:

import os
import time
import random
from multiprocessing import Process, Queue
from threading import Thread
from datetime import datetime
import schedule


def function1(q):
    while True:
        daydate = datetime.now()
        number = random.randrange(1, 215)
        fmt = '(pid: {}) Sent to function2: ({}, {})'
        print(fmt.format(os.getpid(), daydate, number))
        q.put((daydate, number))
        time.sleep(2)


def function2(q):
    while True:
        date, number = q.get()
        fmt = "(pid: {}) Received values from function1: ({}, {})"
        print(fmt.format(os.getpid(), date, number))
        # time.sleep(2) no need to sleep here because q.get will block until
        # new items are available


def computation():
    q = Queue()
    a = Process(target=function1, args=(q,))
    a.start()
    b = Process(target=function2, args=(q,))
    b.start()
    a.join()
    b.join()


if __name__ == "__main__":

    # We are spawning new threads as a launching platform for
    # computation. Without it, the next job couldn't start before the last
    # one has finished. If your jobs always end before the next one should 
    # start, you don't need this construct and you can just pass 
    # ...do(computation)
    schedule.every().friday.at("01:02").do(
        Thread(target=computation).start
    )
    schedule.every().friday.at("01:03").do(
        Thread(target=computation).start
    )

    while True:
        schedule.run_pending()
        time.sleep(1)

就像现在一样,您的进程在启动一次后将永远运行。如果这不是您想要的,您必须考虑实现一些停止条件。

关于python - 属性错误: Can't pickle local object 'computation.。使用多处理队列的 function1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52091113/

相关文章:

python - 多处理队列未加入

postgresql - 如何在多个进程之间共享一组数据?

python - 多处理 Pipe() 不起作用

Python PIL - 寻找最近的颜色(舍入颜色)

python - 如何在不完成的情况下分析python的性能?

c++ - 在 C++ 中使用 vector 实现简单的优先级队列

c++ - BFS(广度优先搜索)邻接矩阵C++

docker - docker compose 如何在后台工作?

python - 使用 S3 子文件夹作为 Django 收集静态目标

python - 重命名 Pandas 中的选定列