9

私はすでに1年前にこの正確な質問をしました。私のアプリケーションはPythonのマルチプロセッシングモジュールを使用しています。これはコマンドラインから実行すると正常に動作しますが、Pyinstallerを使用して実行可能ファイルとしてパッケージ化すると、複数のプロセスが、実行するはずの関数を実行するのではなく、元のインスタンスの新しいインスタンスとして生成されます。前回だけでなく、他のどこでも私に与えられたアドバイスは、私がこれまでずっとやってきたmultiprocessing.freeze_support(私のブロックの始めに)を呼び出すif __name__ == "__main__":ことですが、私は何らかの理由で突然この問題に再び遭遇しています。他に何がこれを引き起こしている可能性がありますか?

更新:freeze_support()行の存在がこの問題にまったく影響しないことを確認しました。コメントしたりコメントを外したりすると、まったく同じ動作になります。メインウィンドウのコピーが開かれ、何もせずにそこに座っています。これが私のメインPythonモジュールの最後に呼び出されるブロックです。

if __name__ == '__main__':
    freeze_support()

    # (A bunch of commented-out lines)
    main()
4

3 に答える 3

6

私はばかです。--multiprocessing-fork(まあ、そうではないかもしれませんが、それは完全に私のせいでした)マルチプロセッシングは、フラグと親プロセスからパイプへの数値ハンドルの2つの追加引数を使用して実行することにより、プロセスに子プロセスであることを通知します。multiprocessing.freeze_supportこのフラグの存在をチェックして、子プロセスに指定された関数を実行するか、通常のプログラムを実行するかを決定します。とにかく、コマンドライン引数を解析する私の方法が変更されsys.argvました。これにより、フラグが削除され、子プロセスが新しい親プロセスのように動作するようになりました。

ですから、物語の教訓は、決して変わらないということsys.argvです。optparseフラグの存在について文句を言うuseに切り替えたので、フィルターされた引数のリストを渡す必要がありました。私がこれを行うと、問題は消えました。

于 2012-08-06T14:42:25.027 に答える
2

私は同じ問題を抱えていましたが、すべてのkivyコードが新しいプロセスで実行されるのを避けるために、コードにif句を入れることを解決しました。例えば:

if __name__ == '__main__': # to avoid new window with a new process
    multiprocessing.freeze_support() # support multiprocessing in pyinstaller
    from kivy.lang.builder import Builder
    from kivy.clock import Clock
    from kivy.uix.popup import Popup
    from kivy.uix.textinput import TextInput
    from kivy.uix.scatterlayout import ScatterLayout
    from kivy.graphics.transformation import Matrix
    from kivy.uix.scatter import Scatter
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.properties import BooleanProperty, ListProperty, BoundedNumericProperty, StringProperty, NumericProperty
    from kivy.uix.boxlayout import BoxLayout
    from kivy.app import App
    from kivy.uix.behaviors import ButtonBehavior
    from kivy.uix.image import Image
    from kivy.core.window import Window

それを超えて、kivyを使用するすべてのクラスは、メインプログラムでのエラーを回避するために、同じif句内に配置する必要があります。

私の結論は、kivy、マルチプロセッシング、およびpyinstallerの相互作用により、新しいウィンドウがポップになるということです。Pythonから直接コードを実行する場合、問題は表示されません。私の場合、すでに1つのif句を使用してkivy.core.windowをインポートしていましたが、フリーズサポートを使用していても、Pythonから直接コードを実行しても問題なく動作しましたが、pyinstallerの後では動作しませんでした。

私はそれが誰かを助けることを願っています。

于 2018-10-19T11:05:26.963 に答える
2

setup.pyこれを引き起こす可能性のあるスタイルプログラムの追加の落とし穴:

プログラムを起動するためにエントリポイントを使用している場合は、multiprocessing.freeze_support()内部に配置する必要がある場合がありますmain()

たとえば、 Pyinstaller_setuptoolsは直接呼び出し、ブロックmain()内のすべてのステートメントをスキップしif __name__ == '__main__':ます。

于 2019-12-23T22:24:03.380 に答える