在多个进程中使用 imaplib.IMAP4_SSL

using imaplib.IMAP4_SSL in multiple processes

我想在多个进程中重用 imaplib.IMAP4_SSL 实例,这样我就不必多次登录。 这是一些代码:

import imaplib
from multiprocessing import Process

def fetch(mail_client):
    mail_client.uid('fetch', b'1', 'BODY[TEXT]')

def main():
    c = imaplib.IMAP4_SSL('imap.gmail.com')
    c.login(user='**', password='***')
    c.select('inbox')

    procs = [Process(target=fetch, args=(c,)) for _ in range(100)]
    for p in procs:
        p.start()

    for p in procs:
        p.join()

if __name__ == '__main__':
    main()

但我收到与套接字相关的错误:

imaplib.IMAP4.abort: socket error: [Errno 32] Broken pipe

我认为这是因为进程正在写入同一个套接字,即 imaplib.IMAP4_SSL,所以我尝试添加 multiprocessing.Lock 以防止同时访问:

import imaplib
from multiprocessing import Process, Lock


def fetch(mail_client, lock):
    with lock:
        mail_client.uid('fetch', b'1', 'BODY[TEXT]')


def main():
    c = imaplib.IMAP4_SSL('imap.gmail.com')
    c.login(user='engineering@epallet.com', password='Qwe=1dSAzxc+%')
    c.select('inbox')
    lock = Lock()

    procs = [Process(target=fetch, args=(c, lock)) for _ in range(100)]
    for p in procs:
        p.start()

    for p in procs:
        p.join()


if __name__ == '__main__':
    main()

但错误依然存在。 一些进一步的调查表明,第一个进程调用 mail.uid 成功,但第二个进程仍然获得 imaplib.IMAP4.abort: command: UID => socket error: EOF

我正在使用 Ubuntu 16.04。 非常感谢任何建议。

更新:在堆栈跟踪中发现另一个异常,可能它会导致所有其他异常:

ssl.SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption failed or bad record mac (_ssl.c:2217)`

似乎与此问题相关 Python ssl problem with multiprocessing

似乎是 SSL 的问题。 SSL-wrapped 套接字不能在多个进程中重复使用。我现在正在使用线程,没有 Lock 一切正常。

你不能。 SSL 上下文不在进程之间共享;没有它,加密状态就会不同步。

如果您需要对同一个 IMAP 收件箱执行多个并发操作,则需要与服务器建立多个连接。