동시 맵 및 맵 축소
QtConcurrent::map(), QtConcurrent::mapped() 및 QtConcurrent::mappedReduced() 함수는 QList 와 같은 시퀀스의 항목에 대해 병렬로 연산을 실행합니다. QtConcurrent::map() 은 시퀀스를 제자리에서 수정하고, QtConcurrent::mapped() 는 수정된 내용을 포함하는 새 시퀀스를 반환하며, QtConcurrent::mappedReduced() 는 단일 결과값을 반환합니다.
이 함수들은 Qt Concurrent 프레임워크의 일부입니다.
위의 각 함수에는 QFuture 대신 최종 결과를 반환하는 블로킹 변형이 있습니다. 비동기 변형과 동일한 방식으로 사용합니다.
QList<QImage> images = ...; // Each call blocks until the entire operation is finished. QList<QImage> future = QtConcurrent::blockingMapped(images, scaled); QtConcurrent::blockingMap(images, scale); QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollage);
위의 결과 유형은 QFuture 객체가 아니라 실제 결과 유형(이 경우 QList<QImage> 및 QImage)이라는 점에 유의하세요.
동시 맵
QtConcurrent::mapped()는 입력 시퀀스와 맵 함수를 받습니다. 그런 다음 시퀀스의 각 항목에 대해 이 맵 함수가 호출되고 맵 함수의 반환값이 포함된 새 시퀀스가 반환됩니다.
지도 함수는 다음과 같은 형식이어야 합니다:
U function(const T &t);
T와 U는 어떤 유형이든 가능하지만(심지어 같은 유형일 수도 있음), T는 시퀀스에 저장된 유형과 일치해야 합니다. 이 함수는 수정되거나 매핑된 콘텐츠를 반환합니다.
이 예는 시퀀스의 모든 항목에 스케일 함수를 적용하는 방법을 보여줍니다:
QImage scaled(const QImage &image) { return image.scaled(100, 100); } QList<QImage> images = ...; QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scaled);
맵의 결과는 QFuture 을 통해 제공됩니다. 애플리케이션에서 QFuture 을 사용하는 방법에 대한 자세한 내용은 QFuture 및 QFutureWatcher 설명서를 참조하세요.
시퀀스를 제자리에서 수정하려면 QtConcurrent::map()을 사용합니다. 그런 다음 지도 함수는 다음과 같은 형식이어야 합니다:
U function(T &t);
지도 함수의 반환 값과 반환 유형은 사용되지 않는다는 점에 유의하세요.
QtConcurrent::map()을 사용하는 것은 QtConcurrent::mapped()를 사용하는 것과 비슷합니다:
void scale(QImage &image) { image = image.scaled(100, 100); } QList<QImage> images = ...; QFuture<void> future = QtConcurrent::map(images, scale);
시퀀스가 제자리에서 수정되기 때문에 QtConcurrent::map()은 QFuture 을 통해 결과를 반환하지 않습니다. 하지만 QFuture 와 QFutureWatcher 를 사용하여 지도의 상태를 모니터링할 수 있습니다.
동시 맵 축소
QtConcurrent::mappedReduced()는 QtConcurrent::mapped()와 비슷하지만 새로운 결과가 포함된 시퀀스를 반환하는 대신 감소 함수를 사용하여 결과를 단일 값으로 결합합니다.
감소 함수는 다음과 같은 형식이어야 합니다:
V function(T &result, const U &intermediate)
T는 최종 결과의 유형이고, U는 맵 함수의 반환 유형입니다. 환원 함수의 반환 값과 반환 유형은 사용되지 않습니다.
QtConcurrent::mappedReduced()를 다음과 같이 호출합니다:
void addToCollage(QImage &collage, const QImage &thumbnail) { QPainter p(&collage); static QPoint offset = QPoint(0, 0); p.drawImage(offset, thumbnail); offset += ...; } QList<QImage> images = ...; QFuture<QImage> collage = QtConcurrent::mappedReduced(images, scaled, addToCollage);
reduce 함수는 map 함수가 반환하는 각 결과에 대해 한 번씩 호출되며, 중간값을 결과 변수에 병합해야 합니다. QtConcurrent::mappedReduced()는 한 번에 하나의 스레드만 reduce를 호출하도록 보장하므로 결과 변수를 잠그기 위해 뮤텍스를 사용할 필요가 없습니다. QtConcurrent::ReduceOptions 열거형은 축소가 수행되는 순서를 제어할 수 있는 방법을 제공합니다. QtConcurrent::UnorderedReduce (기본값)을 사용하면 순서가 정의되지 않지만 QtConcurrent::OrderedReduce 을 사용하면 원래 순서대로 축소가 수행됩니다.
추가 API 기능
시퀀스 대신 이터레이터 사용
위의 각 함수에는 시퀀스 대신 이터레이터 범위를 취하는 변형이 있습니다. 시퀀스 변형과 동일한 방식으로 사용할 수 있습니다:
QList<QImage> images = ...; QFuture<QImage> thumbnails = QtConcurrent::mapped(images.constBegin(), images.constEnd(), scaled); // Map in-place only works on non-const iterators. QFuture<void> future = QtConcurrent::map(images.begin(), images.end(), scale); QFuture<QImage> collage = QtConcurrent::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage);
차단 변형
위의 각 함수에는 QFuture 대신 최종 결과를 반환하는 블로킹 변형이 있습니다. 비동기 변형과 동일한 방식으로 사용합니다.
QList<QImage> images = ...; // Each call blocks until the entire operation is finished. QList<QImage> future = QtConcurrent::blockingMapped(images, scaled); QtConcurrent::blockingMap(images, scale); QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollage);
위의 결과 유형은 QFuture 객체가 아니라 실제 결과 유형(이 경우 QList<QImage> 및 QImage)이라는 점에 유의하세요.
멤버 함수 사용
QtConcurrent::map(), QtConcurrent::mapped() 및 QtConcurrent::mappedReduced()는 멤버 함수에 대한 포인터를 받아들입니다. 멤버 함수 클래스 유형은 시퀀스에 저장된 유형과 일치해야 합니다:
// QStringList의 모든 문자열을 압착합니다.QStringList strings = ...;QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);// 이미지 목록에 있는 모든 픽셀의 RGB 값을 바꿉니다.QList<QImage> images = ...;QFuture<QImage> bgrImages = QtConcurrent::mapped(images,static_cast<QImage(QImage::*)() const&>(&QImage::rgbSwapped));// 목록에 있는 모든 문자열의 길이 집합을 생성합니다.QStringList 문자열 = ...;QFuture<QSet<int>> wordLengths = QtConcurrent::mappedReduced(문자열, &QString::length, qOverload<const int&>(&QSet<int>::insert));
qOverload 을 사용하면 여러 개의 과부하가 있는 메서드의 모호성을 해결할 수 있습니다.
또한 QtConcurrent::mappedReduced()를 사용할 때 일반 함수와 멤버 함수를 자유롭게 섞어서 사용할 수 있습니다:
// 일반 함수와 멤버 함수를 섞어서 사용할 수 있습니다.// 문자열 목록의 평균 길이를 계산합니다.extern void computeAverage(int &average, int length);QStringList strings = ...;QFuture<int> averageWordLength = QtConcurrent::mappedReduced(문자열, &QString::length, computeAverage);// 목록에 있는 모든 이미지의 색상 분포 집합을 생성합니다.extern int colorDistribution(const QImage &string);QList<QImage> images = ...;QFuture<QSet<int>> totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution, qOverload<const int&>(&QSet<int>::insert));
함수 객체 사용하기
QtConcurrent::map(), QtConcurrent::mapped(), QtConcurrent::mappedReduced()는 지도 함수에 대한 함수 객체를 받아들입니다. 이러한 함수 객체는 함수 호출에 상태를 추가하는 데 사용할 수 있습니다:
struct Scaled { Scaled(int size) : m_size(size) { } typedef QImage result_type; QImage operator()(const QImage &image) { return image.scaled(m_size, m_size); } int m_size; }; QList<QImage> images = ...; QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));
함수 객체는 reduce 함수에도 지원됩니다:
struct ImageTransform { void operator()(QImage &result, const QImage &value); }; QFuture<QImage> thumbNails = QtConcurrent::mappedReduced(images, Scaled(100), ImageTransform(), QtConcurrent::SequentialReduce);
람다 표현식 사용하기
QtConcurrent::map(), QtConcurrent::mapped(), QtConcurrent::mappedReduced()는 지도와 감소 함수에 대한 람다 표현식을 받아들입니다:
QList<int> vector { 1, 2, 3, 4 }; QtConcurrent::blockingMap(vector, [](int &x) { x *= 2; }); int size = 100; QList<QImage> images = ...; QList<QImage> thumbnails = QtConcurrent::mapped(images, [&size](const QImage &image) { return image.scaled(size, size); } ).results();
QtConcurrent::mappedReduced() 또는 QtConcurrent::blockingMappedReduced()를 사용할 때 일반 함수, 멤버 함수, 람다 식을 자유롭게 섞어서 사용할 수 있습니다.
QList<QImage> collage = QtConcurrent::mappedReduced(images, [&size](const QImage &image) { return image.scaled(size, size); }, addToCollage ).results();
람다를 리듀스 객체로 전달할 수도 있습니다:
QList<QImage> collage = QtConcurrent::mappedReduced(images, [&size](const QImage &image) { return image.scaled(size, size); }, [](QImage &result, const QImage &value) { // do some transformation } ).results();
여러 인수를 받는 함수 래핑하기
두 개 이상의 인수를 받는 맵 함수를 사용하려면 람다 함수 또는 std::bind()
을 사용하여 하나의 인수를 받는 함수로 변환할 수 있습니다.
예를 들어, QImage::scaledToWidth()를 사용하겠습니다:
QImage QImage::scaledToWidth(int width, Qt::TransformationMode) const;
scaledToWidth는 세 개의 인자("this" 포인터 포함)를 취하며, QtConcurrent::mapped()는 하나의 인자를 취하는 함수를 기대하기 때문에 QtConcurrent::mapped()와 함께 직접 사용할 수 없습니다. QImage::scaledToWidth()를 QtConcurrent::mapped()와 함께 사용하려면 폭과 변환 모드에 대한 값을 제공해야 합니다:
QList<QImage> images = ...; std::function<QImage(const QImage &)> scale = [](const QImage &img) { return img.scaledToWidth(100, Qt::SmoothTransformation); }; QFuture<QImage> thumbnails = QtConcurrent::mapped(images, scale);
© 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.