2015-09-05 71 views
3

我已经使用python web框架django制作了一个网站。在我的代码中,我创建了一个django表单并将其显示在home.html中。 django表单从用户处获得一个字符串值,并且该字符串值被用作6个函数中的一个参数。在6个函数完成计算结果后,结果显示在home.html中。Django多重处理

一切正常,但它很慢。慢代码看起来像这样。

def home(request): 
    form = WebForm(request.POST or None) 
    context = { 
     "form" : form, 
    } 

    if form.is_valid(): 
     instance = form.save(commit=False) 
     string_value = form.cleaned_data.get("string_value") 
     if not string_value: 
      string_value = "no string value was entered" 
     instance.string_value = string_value 
     instance.save() 

     # This is where I use the string value as a parameter in my functions 

     my_func1(search) 
     my_func2(search) 
     my_func3(search) 
     my_func4(search) 
     my_func5(search) 
     my_func6(search) 

     # Each function in the previous 6 functions corresponds to a website. Each function finds the first 14 images on its particular website 
     # that correlate to the string value that the user submitted, and appends it to a list (my lists are img1, img2, ..., img6). 
     # The below code is just setting the first 14 elements of each list in a dictionary to be used on home.html 
     conf = {"form" : form} 
     con1 = dict(zip_longest(('img1','img2','img3','img4','img5','img6','img7','img8','img9','img10','img11','img12','img13','img14'), img1[:14])) 
     con21 = dict(zip_longest(('img21','img22','img23','img24','img25','img26','img27','img28','img29','img210','img211','img212','img213','img214'), img2[:14])) 
     con31 = dict(zip_longest(('img31','img32','img33','img34','img35','img36','img37','img38','img39','img310','img311','img312','img313','img314'), img3[:14])) 
     con41 = dict(zip_longest(('img41','img42','img43','img44','img45','img46','img47','img48','img49','img410','img411','img412','img413','img414'), img4[:14])) 
     con51 = dict(zip_longest(('img51','img52','img53','img54','img55','img56','img57','img58','img59','img510','img511','img512','img513','img514'), img5[:14])) 
     con61 = dict(zip_longest(('img61','img62','img63','img64','img65','img66','img67','img68','img69','img610','img611','img612','img613','img614'), img6[:14])) 

     # Now I am combining all of the above dictionaries in to one dictionary 
     context = dict(list(conf.items()) + list(con1.items()) + list(con21.items()) + list(con31.items()) + list(con41.items()) + list(con51.items()) + list(con61.items())) 

    return render(request, "home.html", context) 

为了加速过程中,我使用的多处理。这实际上确实加快了这个过程,我知道这一点,因为我正在计算终端上的数据(数据打印速度更快)。对于多处理,我基本上除去

my_func1(search) 
    my_func2(search) 
    my_func3(search) 
    my_func4(search) 
    my_func5(search) 
    my_func6(search) 

并用

p = Process(target=my_func1, args=(search)) 
p.start() 
p2 = Process(target=my_func2, args=(search)) 
p2.start() 
p3 = Process(target=my_func3, args=(search)) 
p3.start() 
p4 = Process(target=my_func4, args=(search)) 
p4.start() 
p5 = Process(target=my_func5, args=(search)) 
p5.start() 
p6 = Process(target=my_func6, args=(search)) 
p6.start() 

p.join() 
p2.join() 
p3.join() 
p4.join() 
p5.join() 
p6.join() 

取代它。然而,这种方法不显示上home.html的任何数据。详细说明,当用户提交他们的字符串值时,显示的结果是单词None。这表明img1, img2, ..., img6列表是空的,但我知道调用6个函数的多处理代码确实有效,所以我很困惑。

此外,我home.html的页面上的代码看起来是这样的

# In home.html (I am going to add pseudo code to save me some time) 

Code to display the form is here 

all of my image elements are displayed like this 
<h1>{{ img1 }}</h1> 

是否有人可以帮助我,我将极大地欣赏它。谢谢。

回答

1

你似乎没有收回数据的原因是你产卵的子进程来执行任务,但孩子们不通知父母他们产生了什么结果。

您应该考虑this documentation sample关于进程之间的共享状态,并调整它以共享儿童生成的结果。

从上面的文档链接引用代码片段:

from multiprocessing import Process, Value, Array 

def f(n, a): 
    n.value = 3.1415927 
    for i in range(len(a)): 
     a[i] = -a[i] 

if __name__ == '__main__': 
    num = Value('d', 0.0) 
    arr = Array('i', range(10)) 

    p = Process(target=f, args=(num, arr)) 
    p.start() 
    p.join() 

    print(num.value) 
    print(arr[:]) 

注意,这不是一个真正的特定Django的细节。这只是关于进程间通信,应该在一般情况下有用。

UPDATE

此更新是考虑到大家的一些问题在下面的评论部分。

我不明白以name =='main' 在做什么开头的短语。

if __name__ == '__main__'不是一个赋值,它是一个用于防止意外代码执行的比较(注意double ==而不是单个=)。每当Python模块直接启动时,其名称将为'__main__',并且会按预期运行,但是当从其他模块(例如使用pydoc3)导入时,__name__将会不同,并且检查将失败,从而阻止程序从实际运行,这是你想要的。

据分配num作为具有0.0的初始值的两倍,并arr与那些range(10)整数元素的数组。

的文档是你的朋友:

它的存在,回答这类问题:)

而且,我会怎样用字符串14 stri启动一个数组ng元素? 这项工作arr = Array('string', len(14))

这不起作用,因为len函数需要一个序列或集合,而您要发送一个标量值(即14)。

我建议你写一个简短的测试程序,看看他们是如何工作的。我认为学习更有效。例如:

>>> from multiprocessing import Array 
>>> a = Array('i', 3) # Array of integers with 3 elements 
>>> for i in a: print(i) 
... 
0 
0 
0 
>>> 

PS:我已经打消了我以前的评论,这是本次升级的基础。

+0

我阅读文档,但我很困惑。我不明白以__name__ =='__main__'开头的短语在做什么。它是否将num分配为带有一个小数位的double值,并将arr分配为具有10个整数元素的数组? – SagwaTheCat

+0

其实,我想我知道它在做什么,但告诉我,如果我错了。它将num赋值为初始值为0.0的double,将arr赋值为范围为(10)的整数元素的数组。 – SagwaTheCat

+0

另外,我将如何启动一个数组与字符串14字符串元素?这会工作arr = Array('string',len(14))? – SagwaTheCat