プライム・カウンター

並行処理の進行状況を監視する方法を示します。

次の例では、QFutureWatcher クラスとfilteredReduced関数を使用して、インタラクティブでノンブロッキングな QtWidgets アプリケーションを作成する方法を示します。 Qt Concurrent.この例では、ユーザはQList のサイズを変更できる整数を作成できます。リストは1からnまでの自然数で自動的に埋められます。プログラムはリスト内の素数をチェックし、見つかった素数の総数を表示します。

例題の実行

から例を実行するには Qt Creatorから例を実行するには、Welcome モードを開き、Examples から例を選択する。より詳しい情報は、Building and Running an Exampleを参照。

接続の設定

接続の設定 Qt ConcurrentライブラリはfilteredReduced関数を提供しており、OrderedReduce and UnorderedReduce の2つのモードで動作します。OrderedReduceUnorderedReduce 。 モードでは、要素はランダムにアクセスされます。

必要な要素でUIを構成した後、QtSignals & Slotsメカニズムを使って、並行処理のシグナルに接続する必要があります。この例では、QFutureWatcher クラスを使用して並行処理の進行状況を監視し、対話型 GUI の実装に必要なシグナルを提供します。

    ...
connect(ui->pushButton, &QPushButton::clicked,
        this, [this] { start(); });
connect(&watcher, &QFutureWatcher<Element>::finished,
        this, [this] { finish(); });
connect(&watcher, &QFutureWatcher<Element>::progressRangeChanged,
        ui->progressBar, &QProgressBar::setRange);
connect(&watcher, &QFutureWatcher<Element>::progressValueChanged,
        ui->progressBar, &QProgressBar::setValue);
    ...

QFutureWatcher クラスは、並行処理の変更に応じて UI を更新するために必要なシグナルを提供するため、この例では重要な役割を果たします。

並行処理の開始

すべてのシグナルとスロットを接続した後、ユーザーがQPushButtonを押すと、start() 関数が呼び出されます。

start() 関数では、Qt Concurrent からfilteredReduced関数を呼び出し、QFutureWatcher メンバにfutureを設定します。この操作が真に同時並行的に実行されるようにするため、QThreadPool を最初のパラメータとして別に指定します。この方法によって、グローバル・スレッド・プールでのブロッキングも回避できる。コンテナとして整数のQList 、静的フィルタとreduce関数、最後にReduceOption フラグを渡します。

    ...
void PrimeCounter::start()
{
    if (ui->pushButton->isChecked()) {
        ui->comboBox->setEnabled(false);
        ui->pushButton->setText(tr("Cancel"));
        ui->labelResult->setText(tr("Calculating ..."));
        ui->labelFilter->setText(tr("Selected Reduce Option: %1").arg(ui->comboBox->currentText()));
        fillElementList(ui->horizontalSlider->value() * stepSize);

        timer.start();
        watcher.setFuture(
            QtConcurrent::filteredReduced(
                &pool,
                elementList,
                filterFunction,
                reduceFunction,
                currentReduceOpt | QtConcurrent::SequentialReduce));
    ...

filter関数とreduce関数を見てみよう。これらの関数はメンバ変数に依存しないので、この例では静的と宣言されています。しかし、これらはラムダやメンバ関数として簡単に指定できます。

filter関数は、reduce関数で削減する要素をマークします。この実装は単純な素数フィルターです。この関数は引数としてconst参照を取るので、操作対象のコンテナに対してスレッドセーフな操作が可能です。

    ...
bool PrimeCounter::filterFunction(const Element &element)
{
    // Filter for primes
    if (element <= 1)
        return false;
    for (Element i = 2; i*i <= element; ++i) {
        if (element % i == 0)
            return false;
    }
    return true;
}
    ...

reduce 関数は、その最初のパラメータとして、操作対象のコンテナと同じ型の変更可能な参照を取ります。2番目のパラメータは、filter関数で以前にフィルタリングされた要素です。この例では、素数の数を数えます。

    ...
void PrimeCounter::reduceFunction(Element &out, const Element &value)
{
    // Count the amount of primes.
    Q_UNUSED(value);
    ++out;
}
    ...

プロジェクト例 @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.