19

私は(自家製の)CベースのPython拡張機能で計算量の多いシミュレーションを実行しています。時々、私は物事を間違えて、シミュレーションを終了したいと思います。ただし、Ctrl-Cは(画面に印刷する以外は)効果がないように見えるため、またはシステムモニター^Cを使用してプロセスを強制終了する必要があります。kill

私が見る限り、PythonはC拡張機能が終了するのを待つだけで、この間は実際には通信しません。

これを機能させる方法はありますか?

更新:(私の特定の問題に対する)主な答えは次のようになりました:1。コードを書き直して、定期的に制御を呼び出し元に戻します(Ctrl-Cが以下のPython C拡張を中断できるようにする答え)、または2. PyErr_CheckSignals()(以下のhttps://stackoverflow.com/a/33652496/423420に回答してください)

4

5 に答える 5

17

ただし、Ctrl-C は効果がないようです

Ctrl-CシェルSIGINTでフォアグラウンド プロセス グループに送信しますpython信号を受信すると、C コードでフラグが設定されます。C 拡張機能がメイン スレッドで実行される場合、Python シグナル ハンドラは実行されません (したがって、 でKeyboardInterrupt例外は表示されませんCtrl-C) を呼び出しPyErr_CheckSignals()てフラグをチェックし (つまり、速度が低下しないことを意味します)、Python を実行します。必要な場合、またはシミュレーションで Python コードの実行が許可されている場合 (たとえば、シミュレーションで Python コールバックが使用されている場合) は、シグナル ハンドラ。@Matt によって提案された pybind11 を使用して作成された CPython の拡張モジュールのコード例を次に示します。

PYBIND11_MODULE(example, m)
{
    m.def("long running_func", []()
    {
        for (;;) {
            if (PyErr_CheckSignals() != 0)
                throw py::error_already_set();
            // Long running iteration
        }
    });
}

拡張機能がバックグラウンド スレッドで実行される場合は、GIL を解放するだけで十分です (シグナル ハンドラーの実行を可能にするメイン スレッドで Python コードを実行できるようにするため)。PyErr_CheckSignals() 常に0バックグラウンド スレッドで返されます。

関連: Cython、Python、および KeybordInterrupt は ingored

于 2015-11-11T14:18:59.697 に答える
8

SIGINTPython には、メイン インタープリター ループによってチェックされるフラグを設定するだけのシグナル ハンドラーがインストールされています。このハンドラーが正しく機能するには、Python インタープリターが Python コードを実行している必要があります。

いくつかのオプションを利用できます。

  1. Py_BEGIN_ALLOW_THREADS/を使用Py_END_ALLOW_THREADSして、C 拡張コードの周りの GIL を解放します。GIL を保持していないときは Python 関数を使用できませんが、Python コード (およびその他の C コード) は C スレッドと同時に実行できます (真のマルチスレッド)。別の Python スレッドを C 拡張機能と並行して実行し、Ctrl+C シグナルをキャッチできます。
  2. 独自のハンドラーを設定しSIGINT、元の (Python) シグナル ハンドラーを呼び出します。その後、ハンドラーSIGINTは、C 拡張コードをキャンセルし、制御を Python インタープリターに戻すために必要なことは何でも実行できます。
于 2013-02-05T13:21:46.857 に答える
0

C 拡張機能を再設計して、長期間実行しないようにします。

したがって、それらをより基本的なステップに分割し (それぞれが短い時間 (たとえば 10 ~ 50 ミリ秒) 実行されます)、これらのより基本的なステップを Python コードで呼び出すようにします。

プログラミングスタイルとして、継続渡しスタイルは理解するのに関連しているかもしれません...

于 2013-02-05T12:13:23.720 に答える