프라임 카운터

동시 작업의 진행 상황을 모니터링하는 방법을 보여줍니다.

다음 예제는 QFutureWatcher 클래스와 필터링된Reduced 함수를 사용하여 대화형 비차단 QtWidgets 애플리케이션을 만드는 방법을 보여줍니다. Qt Concurrent. 이 예제에서 사용자는 크기를 조정할 수 있는 정수로 구성된 QList 을 만들 수 있습니다. 이 목록은 1부터 n까지 시작하는 자연수로 자동으로 채워지며, 프로그램은 목록 내에서 소수를 확인하고 발견된 소수의 총 개수를 표시합니다.

예제 실행하기

에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.

연결 설정하기

라이브러리는 Qt Concurrent 라이브러리는 OrderedReduce and UnorderedReduce 의 두 가지 모드에서 작동할 수 있는 필터링된Reduced 함수를 제공합니다. OrderedReduce 모드에서는 원래 순서대로 환원 함수가 호출되는 반면, UnorderedReduce 모드에서는 요소에 무작위로 액세스합니다.

원하는 요소로 UI를 구성한 후에는 Qt Signals & 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 멤버에 미래를 설정합니다. 이 작업이 실제로 동시에 실행되도록 하기 위해 첫 번째 매개변수로 별도의 QThreadPool 을 지정합니다. 이 접근 방식은 또한 글로벌 스레드 풀에서 발생할 수 있는 모든 차단을 방지합니다. 컨테이너로 정수의 QList, 정적 필터 및 축소 함수, 마지막으로 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));
    ...

필터와 축소 함수를 살펴봅시다. 이러한 함수는 멤버 변수에 의존하지 않기 때문에 이 예제에서는 정적으로 선언되었습니다. 그러나 람다 또는 멤버 함수로 쉽게 지정할 수 있습니다.

필터 함수는 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 함수는 연산하는 컨테이너와 동일한 유형의 수정 가능한 참조를 첫 번째 매개변수로 받습니다. 두 번째 매개변수는 필터 함수에서 이전에 필터링된 요소입니다. 이 예에서는 소수의 수를 계산합니다.

    ...
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.