[C++11 并发编程] 动态选择并发线程的数量

C++ 并行编程(thread)---多线程_c++ thread process_泠山的博客-CSDN博客进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程——资源分配的最小单位。线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。是程序执行的最小单位。_c++ thread processhttps://blog.csdn.net/qq_28087491/article/details/127464635

C++标准模板库提供了一个辅助函数 - std::thread::hardware_concurrency(),通过这个函数,我们可以获取应用程序可以真正并发执行的线程数量。下面这个例子,实现了一个并发版本的std::accumulate,它将工作拆分到多个线程中,为了避免过多线程带来的开销,程序指定了每个线程处理数据的最小数量。


头文件和求和操作:

sum.hpp

#include <thread>
#include <numeric>
#include <algorithm>
#include <functional>
#include <vector>
#include <iostream>
 
template<typename Iterator,typename T>
struct accumulate_block
{
    void operator()(Iterator first,Iterator last,T& result)
    {
        result=std::accumulate(first,last,result);
    }
};

sum.cpp

#include <numeric>
#include <chrono>
#include "sum.hpp"

template<typename Iterator,typename T>
T parallel_accumulate(Iterator first,Iterator last,T init)
{
    unsigned long const length = std::distance(first,last);
    
    // 若输入数据为空,则返回初始值
    if(!length)
        return init;
    
    // 计算所需要的最大线程数量,每个线程至少计算25个数据
    unsigned long const min_per_thread = 25;

    unsigned long const max_threads = (length+min_per_thread-1)/min_per_thread;
    
    // 获取硬件可并发线程数量
    unsigned long const hardware_threads = std::thread::hardware_concurrency();
    
    // 计算实际要创建的线程数量
    unsigned long const num_threads = std::min(hardware_threads != 0 ?hardware_threads:2,max_threads);
    
    // 根据线程数量,拆分数据
    unsigned long const block_size = length/num_threads;
    
    // 创建用于存放每个线程计算结果的容器和线程
    std::vector<T> results(num_threads);
    std::vector<std::thread> threads(num_threads-1);
    
    Iterator block_start=first;
    for(unsigned long i=0;i<(num_threads-1);++i)
    {
        Iterator block_end=block_start;
        // 移动迭代器
        std::advance(block_end,block_size);
        // 启动新线程,对一块数据进行处理
        threads[i]=std::thread(accumulate_block<Iterator,T>(),block_start,block_end,std::ref(results[i]));
        // 为下一个线程准备数据
        block_start=block_end;
    }
    
    // 当启动了所有的子线程对数据进行计算,本线程就对数据的最后一块进行计算
    accumulate_block<Iterator,T>()(block_start,last,results[num_threads-1]);
    // 使用fore_each对所有的线程执行join操作,等待它们执行结束
    std::for_each(threads.begin(),threads.end(),std::mem_fn(&std::thread::join));
    // 最后对所有的计算结果求和
    return std::accumulate(results.begin(),results.end(),init);
}


int main()
{
    std::cout << "threads: " << std::thread::hardware_concurrency() << std::endl;
    std::vector<int> vi;
    for(int i=0;i<1000000000;++i)
    {
        vi.push_back(i);
    }
    auto start = std::chrono::system_clock::now();

    int sum=parallel_accumulate(vi.begin(),vi.end(),9);

    auto end = std::chrono::system_clock::now();

    std::chrono::duration<double> diff = end-start;

    std::cout << "parallel_accumulate Time: " << diff.count() << " s\n";


    std::cout<<"sum="<<sum<<std::endl;
}



 结果:

线程的标识符的类型为std::thread::id,有两种方法可以获取线程的标示符,

一种是通过调用关联到线程的std::thread对象的get_id()方法,

另一种方法是在线程内调用std::this_thread::get_id()

线程标识符通常用于区分主线程子线程,在某些情况下主线程中可以做一些特定的操作

   std::thread::id master_thread;
    void some_core_part_of_algorithm()
    {
        if(std::this_thread::get_id()==master_thread)
        {
            do_master_thread_work();
        }
        do_common_work();
    }


原文链接:https://blog.csdn.net/yamingwu/article/details/47355921

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值