如何使用多处理创建 nntplib 对象
How to create nntplib objects using Multiprocessing
在创建与 NNTP 服务器的连接时,尝试 2 天让多处理工作。目标:尽可能快地建立一堆连接(比如 50 个)。由于在 for 循环中建立连接可能很慢(例如最多 10 秒),我想使用多处理将它们全部 'at once'。创建连接后,它们保持打开状态,因为在未来的某个多处理部分将发出 10,000+ 请求,依赖于类似的原则。
部分代码简化:
#!/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 服务器等的连接有效,但我无法将连接提取到某个对象中,我可以将其与 nntplib 选项结合使用。我会说我对 python 没有那么多经验,尤其是没有多处理。
您的方法存在一些不同的问题。最大的是在不同的进程中创建连接,然后将它们发送到主进程,这将不起作用。这是因为每个连接都会打开一个套接字,而套接字是不可序列化的(可拾取的),因此不能在进程之间发送。
即使它有效,使用 .apply_sync()
也不是正确的方法。最好使用 .map()
,其中 return 是函数调用的直接输出(相对于 .apply_sync()
,return 是 return 的对象可以提取值)。
但是,在当前情况下,程序是 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
。然而,您可能需要研究一段时间才能熟练使用。
在创建与 NNTP 服务器的连接时,尝试 2 天让多处理工作。目标:尽可能快地建立一堆连接(比如 50 个)。由于在 for 循环中建立连接可能很慢(例如最多 10 秒),我想使用多处理将它们全部 'at once'。创建连接后,它们保持打开状态,因为在未来的某个多处理部分将发出 10,000+ 请求,依赖于类似的原则。
部分代码简化:
#!/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 服务器等的连接有效,但我无法将连接提取到某个对象中,我可以将其与 nntplib 选项结合使用。我会说我对 python 没有那么多经验,尤其是没有多处理。
您的方法存在一些不同的问题。最大的是在不同的进程中创建连接,然后将它们发送到主进程,这将不起作用。这是因为每个连接都会打开一个套接字,而套接字是不可序列化的(可拾取的),因此不能在进程之间发送。
即使它有效,使用 .apply_sync()
也不是正确的方法。最好使用 .map()
,其中 return 是函数调用的直接输出(相对于 .apply_sync()
,return 是 return 的对象可以提取值)。
但是,在当前情况下,程序是 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
。然而,您可能需要研究一段时间才能熟练使用。