如何使用多处理创建nntplib对象

2024-05-28 19:34:09 发布

您现在位置:Python中文网/ 问答频道 /正文

在创建到NNTP服务器的连接时,尝试2天以使多进程工作。目标:尽可能快地建立一组连接(比如50个)。由于在for循环中建立连接可能会很慢(比如最多10秒),因此我希望使用多处理“一次”建立所有连接。在创建连接之后,它们仍然是开放的,因为根据类似的原理,在将来的一些多处理部分中会发出10000+的请求。你知道吗

代码的一些简化部分:

#!/usr/bin/env python3

import sys
import ssl
from nntplib import NNTP_SSL
from multiprocessing import Pool 

def MakeCon(i, host, port):
    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    s = NNTP_SSL(host, port=port, ssl_context=context, readermode=True)
    print('created connection', i)  # print to see progress
    sys.stdout.flush()
    return s

def Main():
    host = 'reader.xsnews.nl'
    port = 563
    num_con = 4

    y=MakeCon(1, host, port).getwelcome()  #request some message from NNTP host to see if it works
    print(y)

    # the actual part that has the issue:
    if __name__ == '__main__':

        cons = range(num_con)
        s = [None] * num_con
        pool = Pool()
        for con in cons:
            s[con]=pool.apply_async(MakeCon, args=(con, host, port))
        pool.close

        print(s[1])
        for con in cons:
            t=s[con].getwelcome()  #request some message from NNTP host to see if it works
            print(t)

        print('end')

Main()

显示到NNTP服务器etc的连接可以工作,但是我在将连接提取到某个对象(可以与nntplib选项结合使用)的部分失败。我想说我对python没有那么丰富的经验,尤其是在多处理方面。你知道吗


Tags: tofromimporthostsslforifport
1条回答
网友
1楼 · 发布于 2024-05-28 19:34:09

你的方法有几个不同的问题。最大的问题是,在不同的进程中创建连接,然后将它们发送到主进程是行不通的。这是因为每个连接打开一个套接字,并且套接字不可序列化(可拾取),因此不能在进程之间发送。你知道吗

即使它起了作用,使用.apply_sync()也不是正确的方法。最好使用.map()直接返回函数调用的输出(而不是.apply_sync()返回可以从中提取返回值的对象)。你知道吗

但是,在当前情况下,程序是受I/O限制的,而不是受CPU限制的,在这些情况下,线程处理与多处理一样有效,因为GIL不会阻止执行。因此,更改为线程而不是多处理,并从.apply_sync()更改为.map()可提供以下解决方案:

#!/usr/bin/env python3

import sys
import ssl
from nntplib import NNTP_SSL
from multiprocessing.pool import ThreadPool 

def MakeCon(i, host, port):
    context = ssl.SSLContext(ssl.PROTOCOL_TLS)
    s = NNTP_SSL(host, port=port, ssl_context=context, readermode=True)
    print('created connection', i)  # print to see progress
    sys.stdout.flush()
    return s

def Main():
    host = 'reader.xsnews.nl'
    port = 563
    num_con = 4

    y=MakeCon(1, host, port).getwelcome()  #request some message from NNTP host to see if it works
    print(y)
    return con

    cons = range(num_con)
    s = [None] * num_con
    pool = ThreadPool()
    s=pool.map(lambda con: MakeCon(con, host, port), cons)
    pool.close

if __name__ == "__main__":
    Main()

不过,给你一点建议。要小心创建太多的连接,因为这可能无法从服务器上很好地查看,因为这样做会消耗资源。你知道吗

另外,如果您要使用不同的连接来获取文章,那么这些调用可能也应该在不同的线程中完成。你知道吗

最后一点,与使用线程相同的效果是使用asyncio。然而,这是你可能需要研究一段时间,然后你觉得舒适的使用。你知道吗

相关问题 更多 >

    热门问题