如何在 Python 网络机器人中有效地实施 multithreading/multiprocessing?
How can I efficiently implement multithreading/multiprocessing in a Python web bot?
假设我有一个用 python 编写的网络机器人,它通过 POST 请求向网站发送数据。数据逐行从文本文件中提取并传递到数组中。目前,我正在通过一个简单的 for 循环测试数组中的每个元素。我怎样才能有效地实现多线程以更快地迭代数据。假设文本文件相当大。将线程附加到每个请求是否聪明?您认为最好的方法是什么?
with open("c:\file.txt") as file:
dataArr = file.read().splitlines()
dataLen = len(open("c:\file.txt").readlines())-1
def test(data):
#This next part is pseudo code
result = testData('www.example.com', data)
if result == 'whatever':
print 'success'
for i in range(0, dataLen):
test(dataArr[i])
我正在考虑与此类似的事情,但我觉得这会导致问题,具体取决于文本文件的大小。我知道存在允许最终用户在处理大量数据时指定线程数量的软件。我不完全确定它是如何工作的,但这是我想要实现的。
import threading
with open("c:\file.txt") as file:
dataArr = file.read().splitlines()
dataLen = len(open("c:\file.txt").readlines())-1
def test(data):
#This next part is pseudo code
result = testData('www.example.com', data)
if result == 'whatever':
print 'success'
jobs = []
for x in range(0, dataLen):
thread = threading.Thread(target=test, args=(dataArr[x]))
jobs.append(thread)
for j in jobs:
j.start()
for j in jobs:
j.join()
由于 Global Interpreter Lock,线程在 python 中很慢。您应该考虑在 Python multiprocessing
模块中使用多个进程而不是线程。使用多个进程可以增加代码的 "ramp up" 时间,因为产生一个真正的进程比一个轻线程需要更多的时间,但是由于 GIL,threading
不会做你想要的。
Here and here 是一些关于使用 multiprocessing
模块的基本资源。这是第二个示例 link:
import multiprocessing as mp
import random
import string
# Define an output queue
output = mp.Queue()
# define a example function
def rand_string(length, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str = ''.join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put(rand_str)
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, output)) for x in range(4)]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
# Get process results from the output queue
results = [output.get() for p in processes]
print(results)
这听起来像是 multiprocessing.Pool
的食谱
看这里:https://docs.python.org/2/library/multiprocessing.html#introduction
from multiprocessing import Pool
def test(num):
if num%2 == 0:
return True
else:
return False
if __name__ == "__main__":
list_of_datas_to_test = [0, 1, 2, 3, 4, 5, 6, 7, 8]
p = Pool(4) # create 4 processes to do our work
print(p.map(test, list_of_datas_to_test)) # distribute our work
输出如下:
[True, False, True, False, True, False, True, False, True, False]
假设我有一个用 python 编写的网络机器人,它通过 POST 请求向网站发送数据。数据逐行从文本文件中提取并传递到数组中。目前,我正在通过一个简单的 for 循环测试数组中的每个元素。我怎样才能有效地实现多线程以更快地迭代数据。假设文本文件相当大。将线程附加到每个请求是否聪明?您认为最好的方法是什么?
with open("c:\file.txt") as file:
dataArr = file.read().splitlines()
dataLen = len(open("c:\file.txt").readlines())-1
def test(data):
#This next part is pseudo code
result = testData('www.example.com', data)
if result == 'whatever':
print 'success'
for i in range(0, dataLen):
test(dataArr[i])
我正在考虑与此类似的事情,但我觉得这会导致问题,具体取决于文本文件的大小。我知道存在允许最终用户在处理大量数据时指定线程数量的软件。我不完全确定它是如何工作的,但这是我想要实现的。
import threading
with open("c:\file.txt") as file:
dataArr = file.read().splitlines()
dataLen = len(open("c:\file.txt").readlines())-1
def test(data):
#This next part is pseudo code
result = testData('www.example.com', data)
if result == 'whatever':
print 'success'
jobs = []
for x in range(0, dataLen):
thread = threading.Thread(target=test, args=(dataArr[x]))
jobs.append(thread)
for j in jobs:
j.start()
for j in jobs:
j.join()
由于 Global Interpreter Lock,线程在 python 中很慢。您应该考虑在 Python multiprocessing
模块中使用多个进程而不是线程。使用多个进程可以增加代码的 "ramp up" 时间,因为产生一个真正的进程比一个轻线程需要更多的时间,但是由于 GIL,threading
不会做你想要的。
Here and here 是一些关于使用 multiprocessing
模块的基本资源。这是第二个示例 link:
import multiprocessing as mp
import random
import string
# Define an output queue
output = mp.Queue()
# define a example function
def rand_string(length, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str = ''.join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put(rand_str)
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, output)) for x in range(4)]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
# Get process results from the output queue
results = [output.get() for p in processes]
print(results)
这听起来像是 multiprocessing.Pool
看这里:https://docs.python.org/2/library/multiprocessing.html#introduction
from multiprocessing import Pool
def test(num):
if num%2 == 0:
return True
else:
return False
if __name__ == "__main__":
list_of_datas_to_test = [0, 1, 2, 3, 4, 5, 6, 7, 8]
p = Pool(4) # create 4 processes to do our work
print(p.map(test, list_of_datas_to_test)) # distribute our work
输出如下:
[True, False, True, False, True, False, True, False, True, False]