首页 > 解决方案 > 执行 Django 管理命令,在 windows 和 linux 中启动多个进程和线程

问题描述

我对多线程和多处理比较陌生。当我刚刚意识到 windows 和 linux 处理多处理的方式非常不同时,我刚刚遇到了另一个学习障碍。我不知道技术细节,但我知道它是不同的。

我正在使用 django 来执行我的应用程序:python manage.py random_script在 random_script 中,我正在导入多处理并旋转不同的进程。我收到以下错误:

  File "<string>", line 1, in <module>
  File "C:\FAST\Python\3.6.4\lib\multiprocessing\spawn.py", line 99, in spawn_main
    new_handle = reduction.steal_handle(parent_pid, pipe_handle)
  File "C:\FAST\Python\3.6.4\lib\multiprocessing\reduction.py", line 82, in steal_handle
    _winapi.PROCESS_DUP_HANDLE, False, source_pid)
OSError: [WinError 87] The parameter is incorrect

我尝试在顶部添加它,因为我的开发服务器是 windows,但我的生产服务器是 linux:

if 'win' in sys.platform:
    print('Window')
    multiprocessing.set_start_method('spawn')
else:
    print('Linux')
    multiprocessing.set_start_method('fork')

但是没有成功。当我继续浏览谷歌时,它建议在该if __name__ == '__main__':行下写下产生的过程部分。如果我正常执行我的脚本(即python random_script.py),那会很好,但我不是。我的想法已经用完了,不再知道如何进行。

++ 编辑 ++

管理.py

#!/usr/bin/env python
import os
import sys
import argparse

DEFAULT_SETTINGS_MODULE = "api.test_settings"

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", DEFAULT_SETTINGS_MODULE)
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        # The above import may fail for some other reason. Ensure that the
        # issue is really that Django is missing to avoid masking other
        # exceptions on Python 2.
        try:
            import django
        except ImportError:
            raise ImportError(
                "Couldn't import Django. Are you sure it's installed and "
                "available on your PYTHONPATH environment variable? Did you "
                "forget to activate a virtual environment?"
            )
        raise
    execute_from_command_line(sys.argv)

随机脚本.py:

class Command(BaseCommand):
    def __init__(self):
        super().__init__()

    def handle(self, *args, **kwargs):
        <...>
        self.main()

    def main(self):
        <...>

上面是我的 manage.py 和我的 random_script.py。

谢谢指导

标签: djangopython-3.xwindowspython-multiprocessing

解决方案


每个应用程序都有初始化/启动它的主模块。

对于 Django 手动运行管理命令manage.py,您可以在其中设置所需的方法:

# manage.py
...

if __name__ == "__main__":
    import multiprocessing
    if 'win' in sys.platform:
        multiprocessing.set_start_method('spawn')
    else:
        multiprocessing.set_start_method('fork')

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
...

以及自定义管理命令示例:

# random_script.py


def calculation(x):
    import time
    time.sleep(1)
    return x


class Command(BaseCommand):

    def handle(self, *args, **options):
        calc_args = [1, 2, 3, 4, 5]
        with multiprocessing.Pool(processes=3) as pool:
            results = pool.map(calculation, calc_args)
        self.stdout.write(
            self.style.SUCCESS('Success: %s' % results)
        )

推荐阅读