在多个进程中使用imaplib.IMAP4_SSL

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在多个进程中使用imaplib.IMAP4_SSL相关的知识,希望对你有一定的参考价值。

我想在许多进程中重用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()

但是我得到了与socket相关的错误:

imaplib.IMAP4.abort:套接字错误:[Errno 32]管道损坏

我认为这是因为进程正在写入同一个套接字,即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。任何建议都非常感谢。

更新:在stacktrace中发现另一个异常,可能会导致所有其他异常:

ssl.SSLError:[SSL:DECRYPTION_FAILED_OR_BAD_RECORD_MAC]解密失败或记录错误mac(_ssl.c:2217)`

似乎这个问题与Python ssl problem with multiprocessing有关

答案

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

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

另一答案

似乎是SSL的问题。 SSL包装的套接字不能在多个进程上重用。我现在正在使用线程,没有Lock,一切都很好。

以上是关于在多个进程中使用imaplib.IMAP4_SSL的主要内容,如果未能解决你的问题,请参考以下文章

使用 imaplib 和 oauth 连接 Gmail

使用 imaplib 和 oauth 连接 Gmail

Imaplib 中的 EOF 错误

如何在Python中执行IMAP搜索(使用Gmail和imaplib)?

Python imaplib 使用日期和时间搜索电子邮件

Python 3:通过 uid (imaplib) 将电子邮件移至垃圾箱