精华内容
下载资源
问答
  • C++并发编程实战

    2017-09-10 14:27:18
    C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战C++并发编程实战
  • C++并发编程实战 pdf

    2017-11-02 18:28:25
    C++并发编程实战 C++并发编程实战 C++并发编程实战 C++并发编程实战
  • c++并发编程实战

    2016-12-20 16:15:48
  • 高清彩版 C++ 并发编程实战
  • 三个资料。经典。 C++并发编程实战-目录.pdf C++并发编程实战-正文.pdf C++Concurrency In Action.pd
  • c++ 并发编程实战的源代码,非常有参考价值。高清。。。
  • C++ 并发编程实战

    2018-11-14 17:46:00
    // todo 转载于:https://www.cnblogs.com/herokk/p/9959290.html

    // todo

    转载于:https://www.cnblogs.com/herokk/p/9959290.html

    展开全文
  • C++并发编程实战 示例源源码(C++ Concurrency in Action)
  • C++并发编程实战中文版,为方便阅读自制了书签,对并发编程学习很有帮助
  • C++并发编程实战
  • C++并发编程实战(中文版),带目录超清晰
  • C++ Concurrency in Action.pdf C++并发编程实战,C++11, 英文影印版,可编辑。
  • C++并发编程实战 示例源源码 (C++ Concurrency in Action)
  • c++并发编程实战(C++11)pdf 高清

    万次阅读 2017-12-11 15:20:00
    C++并发编程实战PDF高清完整版下载。C++并发编程实战PDF是一本非常热门的电子图书。这本书籍是由由威廉姆斯所著的,里面拥有非常详细的讲解,对于新手来说是本不错的书。 下载地址:...

    C++并发编程实战PDF高清完整版下载。C++并发编程实战PDF是一本非常热门的电子图书。这本书籍是由由威廉姆斯所著的,里面拥有非常详细的讲解,对于新手来说是本不错的书。
    下载地址:http://download.csdn.net/download/longmao911/9514923?utm_source=blogseo
    C++并发编程实战电子书介绍
    《C++并发编程实战》是一本基于C++11新标准的并发和多线程编程深度指南。内容包括从std::thread、std::mutex、std::future和std::async等基础类的使用,到内存模型和原子操作、基于锁和锁数据结构的构建,再扩展到并行算法、线程管理,最后还介绍了多线程代码的测试工作。本书的附录部分还对C++11新语言特性中与多线程相关的项目进行了简要的介绍,并提供了C++11线程库的完整参考。

    这里写图片描述

    展开全文
  • C++并发编程实战(英文版).pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
  • C++并发编程实战 基本说明 本文部分代码来自于书籍"C++并发编程实战",仅作本人学习之用。 文件说明: BackgroundTask.h 与 BackgroundTash.cpp:用来做使用类实例及其成员函数来创建线程的案例 ThreadTest.h 与 ...

    C++并发编程实战

    基本说明

    本文部分代码来自于书籍"C++并发编程实战",仅作本人学习之用。
    文件说明:

    • BackgroundTask.h 与 BackgroundTash.cpp:用来做使用类实例及其成员函数来创建线程的案例
    • ThreadTest.h 与 ThreadTest.cpp: 相关关于标准库线程相关的基础知识的测试函数的声明和定义
    • ThreadGuard.h 与 ThreadGuard.cpp: 对线程对象进行包装以应对发生异常时线程无法正常被join的情况
    • main.cpp 测试ThreadTest中的接口函数

    具体实现

    BackgroundTask.h

    #pragma once
    class BackgroundTask
    {
    public:
    	void doWork();
    
    private:
    	void subWork1();
    	void subWork2();
    };
    
    

    BackgroundTask.cpp

    #include "BackgroundTask.h"
    #include <iostream>
    
    
    void BackgroundTask::doWork()
    {
    	subWork1();
    	subWork2();
    }
    
    void BackgroundTask::subWork1()
    {
    	for (int i = 0; i < 100; i++) {
    		std::cout << "i: " << i  << "\n";
    	}
    }
    
    void BackgroundTask::subWork2()
    {
    	for (char a = 'A'; a <= 'Z'; a++) {
    		std::cout << "character: " << a << "\n";
    	}
    }
    

    ThreadGuard.h

    #pragma once
    #include<thread>
    
    // 对线程对象做封装,保证ThreadGuard对象被析构的时候线程对象m_t直接调用join()
    class ThreadGuard
    {
    public:
    	// explicit: 参数传入时不允许发生隐式类型转换
    	explicit ThreadGuard(std::thread& t) : m_t(t) {}
    
    	~ThreadGuard() {
    		// 对于给定的线程,join函数只能被调用一次,所以之前必须检查其是否为joinable
    		if (m_t.joinable()) {
    			m_t.join();
    			// 若调用的是detach,则会把线程丢在后台运行,则无法等待该线程完成,同时也无法获得对于该线程的引用以
    			// 便于后续操作该线程
    		}
    	}
    
    	// 确保编译器不会自动提供拷贝构造函数和赋值运算符重载函数
    	ThreadGuard(ThreadGuard const&) = delete;
    	ThreadGuard& operator=(ThreadGuard const&) = delete;
    private:
    	std::thread& m_t;
    };
    

    ThreadGuard.cpp

    #include "ThreadGuard.h"
    

    ThreadTest.h

    #pragma once
    #include<string>
    #include<thread>
    #include<vector>
    #include<numeric> // std::accumulate
    #include<functional> // std::mem_fn
    #include<algorithm> // std::min std::for_each
    #include<iostream>
    
    // 调用类实例成员函数来创建线程
    void createThreadByClassInstance();
    //lambda表达式创建线程
    void createThreadByLambda();
    
    
    // 创建线程时向线程内部传递参数
    void printParamter(int p[],int s);
    void createThreadTransmitParameters();
    
    // 引用失效 和 引用有效(其实就是值传递和引用传递的区别)
    void changeArray(int p[], int s);
    // 内部将数组元素传递到线程中
    void threadTransimitParameterByValue();
    void changeString(std::string& svalue);
    void threadTransmitStringByRef();
    
    
    // 线程所有权的转移
    void ftest1();
    void ftest2();
    void threadOwnership1();
    void threadOwnership2();
    void threadOwnership3();
    
    
    // 对线程对象在外面包装一个类,以处理外界程序发生异常情况而导致线程程序无法正常detach或者join的情况
    void printAtoZ();
    void printZeroTo99();
    void ThreadGuardTest();
    
    // 后台运行的线程
    void daemonThread();
    
    // 运行时选择线程数量
    template<typename Iterator,typename T>
    struct accumulate_block {
    	void operator()(Iterator first, Iterator last, T& ss){
    		ss = std::accumulate(first,last,ss); // 求给定范围的元素的和,并指定初值result
    	}
    };
    
    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;
    	unsigned long const min_per_thread = 25;
    	// 长度26以下 使用1个线程
    	// 26及26以上,每满26则增加一个线程
    	unsigned long const max_threads = (length + min_per_thread - 1) / min_per_thread; // 计算整除块,要记住!!!
    	unsigned long const hardware_threads = std::thread::hardware_concurrency(); // 获取硬件支持的线程数
    	std::cout << "硬件支持的线程数: " << hardware_threads << "\n";
    	// 硬件线程可用,取硬件线程数,否则取2
    	// 上述结果与max_threads取小,保证线程数量不会无限增大
    	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); // 每个线程的执行结果
    	// 申请存储每个线程的空间:vector(数量为什么比线程数少1:因为最后一个线程分配得到的数据是不能被block_size整除的,所以最后一块数据需要单独处理)
    	std::vector<std::thread> threads(num_threads - 1);
    
    	Iterator block_start = first;
    	// 将数据分段使用num_threads - 1个线程进行处理,将结果保存在results中
    	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;
    	}
    	// 从头开始计算,不适用多线程
    	// 前面一个括号是对结构体accmulate_block的()进行重载后的调用形式
    	accumulate_block<Iterator, T>()(
    		block_start,
    		last,
    		std::ref(results[num_threads-1])
    		);
    	// 每个线程都执行join使得当前线程必须等待在当前线程中创建的线程执行完成
    	std::for_each(
    		threads.begin(),
    		threads.end(),
    		std::mem_fn(&std::thread::join) // 生成指向成员指针的包装对象,可以存储、复制、及调用指向成员指针
    		);
    	// T sum = std::accumulate(results.begin(),results.end()-1,0);
    	//T sum = 0;
    	// 打印出每一个线程的输出结果
    	for (int i = 0; i < num_threads; i++) {
    		std::cout << "result[" << i << "]: " << results[i] << "\n";
    		//sum += results[i];
    	}
    	/*std::cout << sum <<"   "<< results[results.size() - 1] << "\n";
    	std::cout << (sum == results[results.size() - 1] ? "true" : "false")<<"\n";*/
    	return std::accumulate( // 对所有线程计算出来的数据进行累加返回
    		results.begin(),
    		results.end(),
    		init
    	);
    } 
    
    
    void parallel_accumulateTest();
    
    
    // std::thread::id test
    void threadIdTest();
    

    ThreadTest.cpp

    #include "ThreadTest.h"
    #include "BackgroundTask.h"
    #include <thread>
    #include <iostream>
    #include "ThreadGuard.h"
    
    void createThreadByClassInstance()
    {
    	BackgroundTask f;
    	// std::thread my_thread(f); // 编译不通过
    	std::thread my_thread(&BackgroundTask::doWork, &f);
    	if (my_thread.joinable()) {
    		my_thread.join();
    	}
    	else {
    		std::cout << "thread cannot join!\n";
    	}
    }
    
    
    void createThreadByLambda()
    {
    	// lambda表达式创建线程
    	std::thread t1([](std::string s) {
    		for (int i = 0; i < 100; i++) {
    			std::cout << s << "\n";
    		}
    		}, "leexiaolong"
    	);
    	if (t1.joinable()) {
    		t1.join();
    	}
    	else {
    		std::cout << "thread cannot join!\n";
    	}
    }
    
    void printParamter(int p[], int s)
    {
    	for (int i = 0; i < s; i++) {
    		std::cout << p[i] << "\n";
    	}
    }
    
    void createThreadTransmitParameters()
    {
    	const int sz = 128;
    	int buffer[sz];
    	for (int i = 0; i < sz; i++) {
    		buffer[i] = i;
    	}
    	std::thread t(printParamter, buffer, sz);
    	if (t.joinable()) {
    		t.join();
    	}
    	else {
    		std::cout << "thread cannot join!\n";
    	}
    }
    
    void changeArray(int p[], int s)
    {
    	for (int i = 0; i < s; i++) {
    		p[i] = 100;
    	}
    }
    
    // 其实看传进来的参数值是否会发生变化其实就是弄清楚 引用传递和值传递的区别即可
    // 数组式的指针传递,线程会对数组元素的值进行修改
    void threadTransimitParameterByValue()
    {
    	const int sz=10;
    	int buffer[sz];
    	for (int i = 0; i < sz; i++) {
    		buffer[i] = i;
    	}
    	std::thread t(changeArray,buffer,sz);
    	t.join();
    	for (int i = 0; i < sz; i++) {
    		std::cout <<"change?:   "<< buffer[i] << "\n";
    	}
    }
    
    void changeString(std::string& svalue)
    {
    	std::cout << "origin: " << svalue << "\n";
    	svalue = "Hello world!";
    	std::cout << "new: " << svalue<<"\n";
    }
    
    void threadTransmitStringByRef()
    {
    	std::string hello = std::string("hello CPP");
    	// std::thread t(changeString, hello); // 无法通过编译:“std::invoke”: 未找到匹配的重载函数
    	std::thread t(changeString,std::ref(hello));
    	t.join();
    	std::cout << "After thread over: " << hello << "\n";
    }
    
    void ftest1()
    {
    	for (int i = 0; i < 100; i++) {
    		std::cout << "i: " << i << "\n";
    	}
    }
    
    void ftest2()
    {
    	for (char a = 'A'; a <= 'Z'; a++)
    	{
    		std::cout << a << "\n";
    	}
    }
    
    void threadOwnership1()
    {
    	std::thread t1(ftest1);
    	std::cout <<"@@@@@@@@@@@@@@:  "<< t1.get_id()<<"\n";
    	std::thread t2 = std::move(t1);
    	std::cout << "#############:  " << t2.get_id()<<"\n";
    	t1 = std::thread(ftest2);
    	std::cout << "!!!!!!!!!!!!!:  " << t1.get_id()<<"\n";
    
    	t1.join();
    	t2.join();
    }
    
    
    // 这个版本的代码明显会出现不正当程序行为
    void threadOwnership2()
    {
    	std::thread t1(ftest1);
    	std::cout << "@@@@@@@@@@@@@@:  " << t1.get_id() << "\n";
    	std::thread t2 = std::move(t1);
    	std::cout << "#############:  " << t2.get_id() << "\n";
    	t1 = std::thread(ftest2);
    	std::cout << "!!!!!!!!!!!!!:  " << t1.get_id() << "\n";
    
    	std::thread t3;
    	t1 = std::move(t3); // 此处会导致程序崩溃,必须等待接受线程对象的执行函数完成,即必须等待t1执行完成
    
    	t1.join();
    	t2.join();
    }
    
    // 针对threadOwnership2进行的修改
    void threadOwnership3()
    {
    	std::thread t1(ftest1);
    	std::cout << "@@@@@@@@@@@@@@:  " << t1.get_id() << "\n";
    	std::thread t2 = std::move(t1);
    	std::cout << "#############:  " << t2.get_id() << "\n";
    	t1 = std::thread(ftest2);
    	std::cout << "!!!!!!!!!!!!!:  " << t1.get_id() << "\n";
    
    	std::thread t3;
    	t1.detach();
    	t1 = std::move(t3);
    
    	t2.join();
    }
    
    void printAtoZ()
    {
    	ftest2();
    }
    
    void printZeroTo99()
    {
    	ftest1();
    }
    
    void ThreadGuardTest()
    {
    	std::thread t(printAtoZ);
    	ThreadGuard threadGuard(t);
    	
    	printZeroTo99(); // 即使函数prinZeroTo99发生异常,线程对象t也能正确地被join
    }
    
    void daemonThread()
    {
    	std::cout << "currentThread id: " << std::this_thread::get_id()<<"\n";
    	std::thread t(printAtoZ);
    	std::cout << "thread t id: " << t.get_id() << "\n";
    	if (t.joinable()) {
    		t.detach(); // 将线程t从当前线程中分离出来,使其作为应用程序的后台线程
    	}
    }
    
    
    void parallel_accumulateTest() {
    	//可以调整向量a的元素个数来查看程序运行变化情况
    	std::vector<int> a(26, 6); // 102是不能被25(这是parallel_accumulate中默认指定的分块的大小)整除的
    	std::vector<int>::iterator begin = a.begin();
    	std::vector<int>::iterator end = a.end();
    
    	std::cout<<"final value: "<<parallel_accumulate(begin, end, 0)<<"\n";
    }
    
    void threadIdTest()
    {
    	std::thread t1(printAtoZ);
    	std::thread t2(printZeroTo99);
    	// std::thread::id内部对比较运算符进行了重载,允许进行比较
    	std::thread::id id1 = t1.get_id();
    	std::thread::id id2 = t1.get_id();
    	// id1和id2取的是相同的线程对象
    	t1.join();
    	t2.join();
    
    	if (id1 == id2) {
    		std::cout << "getId: same!\n";
    	}
    	else {
    		std::cout << "getId: not same!\n";
    	}
    	std::thread::id id3 = t2.get_id();
    	if (id1 == id3) {
    		std::cout << "getId: same!\n";
    	}
    	else {
    		std::cout << "getId: not same!\n";
    	}
    	
    }
    
    

    main.cpp

    #include "BackgroundTask.h"
    #include "ThreadTest.h"
    
    
    /*
    * crtdll.dll is a module containing standard C library functions such as printf, memcpy, and cos.
    * crtdll.dll is a system process that is needed for your PC to work properly. It should not be removed.
    */
    
    
    
    
    int main() {
    	/*createThreadByClassInstance();
    	createThreadByLambda();	*/
    	// createThreadTransmitParameters(); 
    	// threadTransimitParameterByValue();
    	// threadTransmitStringByRef(); // 引用传参给线程,线程对外界传进来的变量进行了修改
    	//threadOwnership1();
    	// daemonThread();
    	// parallel_accumulateTest();// 累加并行计算
    	threadIdTest();
    	return 0;
    }
    
    展开全文
  • C++并发编程实战 源码 (C++ Concurrency in Action)
  • C++并发编程实战英文原版,有书签,不是扫描版,打印版,超清晰,因为中文版翻译的有些地方不太好,可以拿英文版对照看
  • 【选】C++并发编程实战_[美]威廉姆斯著_201505 花钱买的高清版本,绝非网上那些乱排版
  • C++并发编程实战(中文版).pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
  • c++并发编程实战》高清pdf

    千次阅读 热门讨论 2019-04-24 18:13:06
    C++并发编程实战电子书介绍 《C++并发编程实战》是一本基于C++11新标准的并发和多线程编程深度指南。内容包括从std::thread、std::mutex、std::future和std::async等基础类的使用,到内存模型和原子操作、...


    C++并发编程实战电子书介绍
    《C++并发编程实战》是一本基于C++11新标准的并发和多线程编程深度指南。内容包括从std::thread、std::mutex、std::future和std::async等基础类的使用,到内存模型和原子操作、基于锁和锁数据结构的构建,再扩展到并行算法、线程管理,最后还介绍了多线程代码的测试工作。本书的附录部分还对C++11新语言特性中与多线程相关的项目进行了简要的介绍,并提供了C++11线程库的完整参考。

    在这里插入图片描述
    扫描回复,10008领取

    展开全文
  • [读书笔记]C++并发编程实战

    千次阅读 2018-06-11 00:01:46
    [读书笔记]C++并发编程实战 原文地址:https://github.com/xuyicpp/multi_threading C++并发编程的内容每一章都从浅入深讲解的很详细,虽然第一遍有一些还不是很懂,例如无锁编程和线程池,以后遇到这些问题可以...
  • 可直接去百度云下载: https://pan.baidu.com/s/1gfKnw3L C++并发编程实战, Anthony Williams, pdf全本 C++ Concurrency in Action

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 464
精华内容 185
关键字:

c++并发编程实战

c++ 订阅