使用django进行多处理

时间:2015-09-05 03:51:47

标签: python html multiprocessing

我使用python web framework django创建了一个网站。在我的代码中,我创建了一个django表单并在home.html上显示。 django表单从用户获取字符串值,该字符串值用作6个函数中的参数。在6个函数完成计算结果后,结果显示在home.html上。

一切都按预期工作,但速度很慢。慢代码看起来像这样。

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 个答案:

答案 0 :(得分: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的细节。这只是关于进程间通信,应该是有用的。

<强>更新

此更新将在下面的评论部分中解释您的一些问题。

  

如果名字=='main',我不明白这句话的开头是什么   正在做。

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

  

它将num指定为初始值为0.0的double,将arr指定为具有range(10)的整数元素的数组。

文档是你的朋友:

可以回答这些问题:)

  

另外,如何使用字符串14字符串元素启动数组?   这会有效吗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:我删除了之前的评论,这是此次更新的基础。