1

高いCPU負荷を要する操作のグループを実行するGTKアプリケーションを拡張しています。GUIのボタンをクリックしてこの操作を停止する可能性を含めたいと思います。問題は、予想通り、操作が完了した直後にボタンからの信号が実際に発火することです。

今のところ、コードは次のようになっています。

[...]
// code snippet to show the dialog and to enable user interactions with the buttons on the lower side of the window
while(TRUE) {
    gint run = gtk_dialog_run (window_main);
    if (run == GTK_RESPONSE_APPLY) {
        gboolean success = start_long_operation();
    }
    else if (run == GTK_RESPONSE_HELP) {
        open_about();
    }
    else if (run == GTK_RESPONSE_CANCEL) {
        stop_long_operation();
    }
    else {
        gtk_widget_destroy (window_main);
        return;
    }
}

busy_statelong操作の関数によってチェックされるグローバル変数を宣言しました。それがTRUEの場合、単に内部ループが循環し続けます。それ以外の場合、ループは終了し、関数は結果を返します。

stop_long_operation()このグローバル変数をFALSEに設定するだけです。

前に書いたように、ウィンドウ全体がブロックされるため、操作が終了するまで「停止」ボタンを押して「送信」することはできません。

gtkのドキュメントで説明されているようにwhile (g_main_context_iteration(NULL, FALSE))、関数内でトリックを使用してみましたが、結果はありません。stop_long_operation()

本当にマルチスレッド機能を設定する必要がありますか?これを回避できますか?助けてくれてありがとう。

4

2 に答える 2

2

長い操作を複数の小さなタスクに分割できる場合は、スレッドの使用を回避できる可能性があります。最も簡単な方法は、 g_idle_add(またはg_idle_add_full )に渡すコールバックを作成することです。コールバックが実行されるたびに、少量の作業が実行され、TRUEが返されます。タスクが完了すると、FALSEが返され、コールバックは再度実行されません。タスクを中断したい場合は、g_idle_addによって返された値をg_source_removeに渡して、コールバックを削除するだけです

操作を分割できない場合は、スレッドがほとんど唯一の選択肢です。 g_thread_newはそれを行うための低レベルの方法ですが、一般的にGThreadPoolを使用する方が簡単です。より高度なオプションは、g_simple_async_result_run_in_threadを使用することです。

于 2012-07-16T00:25:38.480 に答える
1

スレッドを使用したくない場合の別のオプションは次のとおりです(ただし、スレッドを使用する必要があり、これは非常に安全ではありません)。

プロセスを使用します。プロセスははるかに単純であり、柔軟性を高めることができます。これがあなたがする必要があることです:

  • 別のC/C++を作成する/タスクを実行するプログラムが必要な任意の言語
  • spawn()またはを使用してスポーンしますpopen()
  • (オプション)コマンドラインまたはIPCを使用して引数を渡します
  • ボタンが押されたら、kill()UNIXの呼び出し、またはWin32のkill関数を使用してプロセスを強制終了します。UNIXで使用SIGTERMしてハンドラーを登録すると、シャットダウンを制御できます。
于 2012-07-16T00:31:03.707 に答える