我想要实现的目标:
我想同时运行100个进程,因为作为for循环执行它需要花费太多时间。例如:对于For循环,我的函数将等到第一个请求被发送后再发送第二个请求。但我希望这100个请求同时发送。
实际结果:
我的函数不会同时执行该过程。它一个接一个地执行过程。
预期结果:
我试过的:所以我试着用多处理模块同时运行100个进程,但并没有达到预期。当我试图在代码中实现多处理模块时,它的运行方式与没有多处理的版本相同,逐个运行一个进程。
我可能会错过什么。
这是我以前使用的代码。
没有多处理的版本 :
import openpyxl
import requests
def getRowCount(file,sheetName):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetname)
return(sheet.max_row)
def readData(file,sheetName,rownum,columno):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetName)
return sheet.cell(row=rownum, column=columno).value
path = my_excel_file
sheetname = my_sheetname
rows = getRowCount(path,sheetname)
def funct():
for i in range(2, 100):
name = readData(path,sheetname,i,1)
data = "name":{}.format(name)
s = requests.Session()
session = s.post(url,headers=s.headers,data=data)
if __name__ == "__main__":
funct()
这是我试图用来解决问题的代码。
具有多处理的版本:
import openpyxl
import requests
from multiprocessing import Process,Lock
def getRowCount(file,sheetName):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetname)
return(sheet.max_row)
def readData(file,sheetName,rownum,columno):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetName)
return sheet.cell(row=rownum, column=columno).value
path = my_excel_file
sheetname = my_sheetname
rows = getRowCount(path,sheetname)
def thread.task(lock,i):
lock.acquire()
name = readData(path,sheetname,i,1)
data = "name":{}.format(name)
s = requests.Session()
session = s.post(url,headers=s.headers,data=data)
lock.release()
if __name__ == '__main__':
lock = Lock()
processes = [Process(target=thread_task, args=(lock, i)) for i in range(2,100)]
for process in processes:
process.start()
for process in processes:
process.join()
我该怎么做才能同时执行我的所有流程?
如果有比多处理更好的解决方案来实现我想要的,请告诉我。
更新
我现在可以同时运行我的进程了。
具有多处理的更新版本:
import openpyxl
import requests
from multiprocessing import Process,Lock
def getRowCount(file,sheetName):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetname)
return(sheet.max_row)
def readData(file,sheetName,rownum,columno):
workbook = openpyxl.load_workbook(file)
sheet = workbook.get_sheet_by_name(sheetName)
return sheet.cell(row=rownum, column=columno).value
path = my_excel_file
sheetname = my_sheetname
rows = getRowCount(path,sheetname)
def thread.task(i):
name = readData(path,sheetname,i,1)
data = "name":{}.format(name)
s = requests.Session()
session = s.post(url,headers=s.headers,data=data)
if __name__ == '__main__':
processes = [Process(target=thread_task, args=(i,)) for i in range(2,100)]
for process in processes:
process.start()
for process in processes:
process.join()
我删除了代码的锁定,现在它工作了。锁似乎阻止了其他进程同时运行。
您可能想尝试上一层,并使用bash通过在for循环中输入到脚本中的参数来执行并发请求。根据我在您的代码中所读到的内容,您想要并行运行的进程(您正在发出的请求(之间似乎没有任何依赖关系,因此,假设可以安全地将这些进程作为对同一python脚本的100个单独调用来运行,并让操作系统担心并发性。
您应该能够通过在bash-for循环中添加参数来实现这一点,如下所示:
for i in {2..100}
do
run_script.py $i
done
然后在您的python脚本中,您可以使用sys模块获取此参数
if __name__ == "__main__":
i = sys.argv[1] # 0 is the name of the script being ran (e.g. run_script.py)
funct(i)
然后重写funct函数来处理该参数。我希望这能有所帮助!
附言:如果您需要进行更复杂的流程协调,调用库可以提供很大帮助:http://www.pyinvoke.org/
很多人不关心在Python中学习多处理。他们只是想把事情做完。
他们中的一些人使用GNU并行为他们做多处理。这样,他们只需要制作一个带有参数的单线程程序。
在你的情况下,你应该能够做出这样的改变:
def funct(i):
name = readData(path,sheetname,i,1)
data = "name":{}.format(name)
s = requests.Session()
session = s.post(url,headers=s.headers,data=data)
if __name__ == "__main__":if __name__ == "__main__":
funct(sys.argv[1])
然后你可以运行:
seq 200 | parallel --jobs 100 python myscript.py {}