C++11多线程服务器编程Part.1

在之前的学习过程中,关于多线程服务器编程的学习内容主要在Linux上的C语言实现,例如pthread_create,等函数,如今C++11也有很多支持多线程的函数和方法(当然环境选择Linux或者Windows都是可以的),并且更加高效和灵活,学无止境,从这次开始,进入到C++11多线程服务器编程开发的学习中。

C++11提供的的多线程编程接口
高级接口:future,async
低级接口:thread,mutex

#include <vector>
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include <future>
#include <cmath>
#include <string>
#include <cstdlib>
#include <unordered_map>
#include <algorithm>
	/*
	at the STD namespace,thread class is a way to create Thread,in my Example,work is a thread object
	work.join well block the MainThread and ask the "work" thread if over,if the "work" thread is over
	the program well continue to run,otherwise,it well always block 
	*/
void HelloWord()
{
	std::cout << "Hello Work Thread!" << std::endl;
}

int main()
{
	std::thread work(HelloWord);
	std::cout << "Hello Main Thread!" << std::endl;
	work.join();
	return 0;
}

为什么使用多线程

1.随着时代的发展,CPU单核红利已经结束,服务器开发使用多线程大势所趋。
2.多线程有着自身的优势,能有效利用多核计算机的性能。
3.实践验证理论,理论反推动实践,如今操作系统、标准库和第三方库都支持了多线程的API,使用更加方便。
4.多线程和异步I/O的关系,单线程是阻塞I/O,如果操作I/O很耗费时间,势必拖累整体速度,但是多线程不会有这种情况。

#include <vector>
#include <iostream>
#include <iomanip>
#include <thread>
#include <chrono>
#include <future>
#include <cmath>
#include <cstdlib>
#include <algorithm>

//if you need to updata the new work setting,please select The Tools menu and choose "Get Tools and Function" Option

//Learn some useful tips
//std::cout <<typeid(b).name() << std::end; // cout:int  typeid could output the value type
void Function()//This is "auto& i" diofferent with "auto i"
{
	std::string str1 = "hello";
	std::string str2 = "hello";
	for (auto i : str1)
	{
		i = toupper(i);
	}
	std::cout << str1 << std::endl;
	for (auto& i : str2)
	{
		i = toupper(i);
	}
	std::cout << str2 << std::endl;
}

//Attention:when a value's type is cite,if we use auto ,it isn't be a cite,for Example
void Function_2()
{
	int A = 1;
	int& F = A;
	auto B = F;//typeid(B).name()-> int
	auto& C = F;//typeid(C).name()-> int&
	std::cout << typeid(B).name() << std::endl;
	std::cout << typeid(C).name() << std::endl;
}

void Function_3()
{
	const int A = 1;
	auto B = A;//typeid(B).name()-> int
	const int C = A;
	auto& D = C;//typeid(D).name()-> const int
	std::cout << typeid(B).name() << std::endl;
	std::cout << typeid(C).name() << std::endl;
}


//about Multithread test

double Math_algorithm(double value)
{
	if (value <= 0)return value;
	std::this_thread::sleep_for(std::chrono::milliseconds(10));
	return sqrt(sqrt(value * (value - 3)) * value);
}

template<typename Iter,typename Fun>
double Count_up(std::thread::id id,Iter iterBegin, Iter iterEnd, Fun func)
{
	auto this_id = std::this_thread::get_id();
	if (id == this_id)
	{
		std::cout << "This is MainThreadId:" << id << std::endl;
	}
	else
	{
		std::cout << "This is WorkThreadId:" << this_id << std::endl;
	}
	double value = double();
	for (auto iter = iterBegin; iter != iterEnd; iter++)
	{
		value += func(*iter);
	}
	return value;
}

int main()
{
	Function();
	auto MainThreadId = std::this_thread::get_id();
	std::vector<double> db;
	for (int i = 0; i < 1000; i++)
	{
		db.push_back(rand());
	}
	std::cout << db.size() << std::endl;

	double Value = double();
	auto start = clock();
	for (auto& Type : db)
	{
		Value += Math_algorithm(Type);
	}
	//Singlethread pass the test only use a thread
	auto end = clock();
	size_t size = db.size();
	std::cout << "Single thread" << Value <<"It use:"<<(end - start)<< std::endl;
	end = clock();
	//in my setting ,Multithread pass the test use two threads 
	//cut down the vector
	auto AntherIter = db.begin() + size;
	double AntherValue = double();
	//at the MainThread
	double MainHalfValue = Count_up(MainThreadId, db.begin(), AntherIter, Math_algorithm);
	auto IterEnd = db.end();
	//at the WorkThread
	//Important to Learn it ---- MULTITHREAD
	std::thread s([&AntherValue, MainThreadId, AntherIter, IterEnd](){
		AntherValue = Count_up(MainThreadId, AntherIter, IterEnd, Math_algorithm);
	});
	//clear up the pthread
	s.join();
	start = clock();
	std::cout << "Multithread" << AntherValue + MainHalfValue << "It use:" << (start - end) << std::endl;
	return 0;
}

在这里,我使用到了for(auto& value:Type)的遍历方式,这与一般的for(auto value:Type)是不同的,在Function函数中,作出了一个示例来展示他们的不同,使用auto&可以对容器的内容进行修改和更新,这是auto&的隐含功能,在我Main实际操作中,auto&这样写,更加普适罢了,auto也是可以的,这里指出来auto和auto&是由区别的,希望大家知晓。

用到了chrono,future,thread这些C++11的头文件,建议本机使用的VS版本在2012以上。
C++11有许多新特性,比如默认的函数比起C++98要多出移动拷贝构造函数和移动赋值函数,这些新的特性之后会慢慢学习到,现在先从多线程的基础入手,循序渐进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值