多线程执行函数(迭代器版本)

#include <iostream>
#include <numeric>
#include <thread>
#include <vector>

template<typename Iterator, typename T>
struct threadBlock
{
    void operator()(T(*func)(Iterator, Iterator, T), Iterator first, Iterator last, T& result)
    {
        result = func(first, last, result);
    }
};
/**
 *
 * @tparam Iterator 迭代器类型
 * @tparam T 数据类型
 * @param func 执行函数
 * @param first 首个元素
 * @param last 最后一个元素
 * @param init 初始值
 * @param threadNum 线程数
 * @return
 */
template<typename Iterator, typename T>
T execInThread(T(*func)(Iterator, Iterator, T), Iterator first, Iterator last, T init, unsigned int threadNum = 0)
{
    auto length = std::distance(first, last);
    if (length == 0) return init;

    auto  numThreads = std::thread::hardware_concurrency();
    if (threadNum != 0 && threadNum < numThreads)
    {
        numThreads = threadNum;
    }
    if (numThreads == 0) numThreads = 1;

    std::vector<T> results(numThreads);
    Iterator block_start = first;

    if (numThreads > 1)
    {
        auto preThread = static_cast<int>(std::floor(static_cast<float>(length) / static_cast<float>(numThreads)));

        std::vector<std::thread> threads(numThreads - 1);

        for (unsigned long i = 0; i < (numThreads - 1); ++i)
        {
            Iterator block_end = block_start;
            std::advance(block_end, preThread);
            threads[i] = std::thread(threadBlock<Iterator, T>(), func, block_start, block_end, std::ref(results[i]));
            block_start = block_end;
        }
        for (auto& entry : threads)
        {
            entry.join();
        }

    }
    threadBlock<Iterator, T>()(func, block_start, last, results[numThreads - 1]);

    threadBlock<Iterator, T>()(func, results.begin(), results.end(), init);
    return init;
}

template<typename Iterator, typename T>
T testFunction(Iterator first, Iterator last, T init)
{
    T result(init);
    for (Iterator it = first; it < last; ++it)
    {
        result += *it;
    }
    return result;
}
int main()
{
    std::vector<int> nums(5000);
    for (int i = 0; i < 5000; ++i)
    {
        nums.at(i) = i;
    }

    //int result1 = execInThread(std::accumulate, nums.begin(), nums.end(), 0, 2);
    int result2 = execInThread(testFunction, nums.begin(), nums.end(), 0, 2);
    std::cout << result2 << '\n';
}

 

posted @ 2024-08-08 13:07  禅元天道  阅读(7)  评论(0编辑  收藏  举报