私は Django プロジェクトに取り組んでおり、バックエンドの計算速度を向上させようとしています。
このタスクはCPU依存の変換プロセスのようなものだ
これが私の環境です
- Python 3.6.1
- ジャンゴ 1.10
- PostgreSQL 9.6
また、Python マルチプロセッシング ライブラリを使用してコンピューティング API を並列化しようとすると、次のエラーが発生しました。
File "D:\\project\apps\converter\models\convert_manager.py", line 1, in <module>
from apps.conversion.models import Conversion
File "D:\\project\apps\conversion\models.py", line 5, in <module>
class Conversion(models.Model):
File "C:\\virtenv\lib\site-packages\django\db\models\base.py", line 105, in __new__
app_config = apps.get_containing_app_config(module)
File "C:\\virtenv\ib\site-packages\django\apps\registry.py", line 237, in get_containing_app_config
self.check_apps_ready()
File "C:\\lib\site-packages\django\apps\registry.py", line 124, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.")
各プロセスは変換モデルをインポートし、変換モデルは次のようになります
from django.db import models
Conversion(model.Model):
conversion_name = models.CharField(max_length=63)
conversion_user = models.CharField(max_length=31)
conversion_description = models.TextField(blank=True)
...
以下は、並列化したいサンプル関数です。各反復は独立していますが、SQL にアクセスしたり、SQL にデータを挿入したりします。
Class ConversionJob():
...
def run(self, p_list):
list_merge_result = []
for p in p_list:
list_result = self.Couputing_api(p)
list_merge_result.extend(list_result)
そして私がやろうとしているのは
from multiprocessing import Pool
Class ConversionJob():
...
def run(self, p_list):
list_merge_result = []
p = Pool(process=4)
list_result = p.map(self.couputing_api, p_list)
list_merge_result.extend(list_result)
computing_api() では、この API 呼び出しの前に、完了した現在の変換の情報を取得して SQL に保存しようとしますが、これによってエラーが発生しました。
私の質問は
- インポート変換モデルによって「アプリがまだ読み込まれていません」というエラーが発生するのはなぜでしょうか。Google で多くの記事を検索しましたが、実際には問題は解決されませんでした。
各プロセス SpawnPoolWorker-x が生成されているのを確認して、Django サーバーを再度起動しようとすると (なぜでしょうか)、各ワーカーが同じエラーで停止します。
コンピューティング API は SQL にアクセスしようとしますが、この作業をどのように処理するかについては考えていません。(DB 接続を共有するか、各プロセスで新しい接続を作成する)
ベストアンサー1
将来これに遭遇するかもしれない他の人のために:
Python 3.8を実行していて、マルチプロセッシングパッケージを使用しようとしているときにこの問題が発生した場合、サブプロセスが「フォーク」ではなく「スポーン」されている可能性があります。これは、Mac OS上のPython 3.8での変更であり、デフォルトのプロセス開始方法が「フォーク」から「スポーン」に変更されています。これは既知の問題Django と一緒に。
これを回避するには:
import multiprocessing as mp
mp.set_start_method('fork')