[置顶] [C++ 2011 多线程系列一]如何创建线程

 

/*
thread.cpp
演示了创建线程的多种方法
*/

#include <iostream>
#include <sstream>
#include <functional>
#include <thread>
#include <future>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

template<typename T> T stringcat(T &x,T &y)
{
 std::cout<<"stringcat start...."<<endl;
 x += x;
 y += y;

 //睡眠指定毫秒数
 std::this_thread::sleep_for(std::chrono::milliseconds(1000));

 std::cout<<"stringcat end...."<<endl;
 return x + y;
}

template<typename T> class CTheadOperator
{
public:
 T operator()(T &x,T &y);
 //异步发起函数调用
 void async();
 //采有创建线程发起异步调用
 void createthread();
 void createthreadA();
 //采有创建线程发起异步调用,并获取到线程调用结果
 void getthreadresult();
 //采有创建线程发起异步调用,并获取到线程调用结果
 void getthreadresult_lamba();
};

template<typename T> void CTheadOperator<T>::createthread()
{
 std::string x = "x",y = "y";
 auto b = std::bind(stringcat<std::string>,x,y);
 std::cout<<"createthread wait stringcat....\n";
 std::thread tp(b);
 tp.join();
 //注意观察返回值的变化
 std::cout<<"无参数被修改 "<<x<<" "<<y<<endl;
}

template<typename T> void CTheadOperator<T>::createthreadA()
{
 std::string x = "x",y = "y"; 
 std::cout<<"createthreadA wait stringcat....\n";
 std::thread tp(stringcat<std::string>,std::ref(x),y);
 tp.join();
 //注意观察返回值的变化
 std::cout<<"引用透传的参数被修改 "<<x<<" "<<y<<endl;
}

template<typename T> void CTheadOperator<T>::getthreadresult()
{
 std::string x = "x",y = "y";
 std::packaged_task<std::string (std::string,std::string)>  task(std::bind(stringcat<std::string>,x,y));
 std::future<std::string> result = task.get_future();

 std::cout<<"getthreadresult wait stringcat....\n";
 //按引用传,调用结束后,值也没有被修改
 std::thread task_td(std::move(task),std::ref(x),y);
 //输出线程的一些信息,注意看输出乱序了,因为并发的
 std::cout<<"getthreadresult threadid:\n"<<task_td.get_id()<<endl;
 //分离线程
 if(task_td.joinable())
 {
  task_td.detach();
 }

 
 
 //注意观察返回值的变化
 std::cout<<result.get()<<",引用透传的参数没有被修改 "<<x<<" "<<y<<endl;
}

template<typename T> void CTheadOperator<T>::getthreadresult_lamba()
{
 std::string x = "x",y = "y";
 //构造 lamba 表达式 语法:[](参数列表){实现}
 std::packaged_task<std::string (std::string,std::string)>
  package_task([](std::string &x,std::string &y) {
   return stringcat(x,y);}
 );

 std::future<std::string> result = package_task.get_future();
 std::cout<<"getthreadresult_lamba wait stringcat....\n";
 //按引用传,调用结束后,值也没有被修改
 std::thread task(std::move(package_task),std::ref(x),y);
 task.join();

 //注意观察返回值的变化
 std::cout<<result.get()<<",引用透传的参数没有被修改 "<<x<<" "<<y<<endl;
}

template<typename T> void CTheadOperator<T>::async()
{
 std::string x = "x",y = "y";
 //auto handle = std::async(std::launch::deferred,aa<std::string>,std::ref(ss),sss);
 std::future<std::string> handle;
 //异步发起函数调用
 handle = std::async(std::launch::async,stringcat<std::string>,std::ref(x),y);

 std::cout<<"async wait stringcat....\n";
 //注意观察返回值的变化
 std::cout<<handle.get()<<",引用透传的参数被修改 "<<x<<" "<<y<<endl;
}

template<typename T> T CTheadOperator<T>::operator()(T &x,T &y)
{
 return stringcat(x,y);
}

int main(int argc, char* argv[])
{
 using namespace std::placeholders; //for _1, _2, _3... 

 std::string desc = "";
 desc += "例子简单描述了不同的方式创建线程和异步调用的区别;\n";
 desc += "如果单纯的发起一个异步调用,还是采用std::async比较简单,直观,\n";
 desc += "能按引用传参数,同时能便捷的获取到异步调用的结果;\n";
 std::cout<<desc;

 //异步发起函数调用
 std::cout<<"-------------------------------------------------\n\n";
 CTheadOperator<std::string> tp;
 tp.async();

 //采有创建线程发起异步调用
 std::cout<<"-------------------------------------------------\n\n";
 tp.createthread();

 //采有创建线程发起异步调用
 std::cout<<"-------------------------------------------------\n\n";
 tp.createthreadA();

 //采有创建线程发起异步调用,并获取到线程调用结果
 std::cout<<"-------------------------------------------------\n\n";
 tp.getthreadresult();

 //采有创建线程发起异步调用,并获取到线程调用结果
 std::cout<<"-------------------------------------------------\n\n";
 tp.getthreadresult_lamba();

 std::cout<<"-------------------------------------------------\n\n";

 system("pause");

 return 0;
}


VS2012 update 2 运行结果:

 

例子简单描述了不同的方式创建线程和异步调用的区别;
如果单纯的发起一个异步调用,还是采用std::async比较简单,直观,
能按引用传参数,同时能便捷的获取到异步调用的结果;
-------------------------------------------------

async wait stringcat....
stringcat start....
stringcat end....
xxyy,引用透传的参数被修改 xx y
-------------------------------------------------

createthread wait stringcat....
stringcat start....
stringcat end....
无参数被修改 x y
-------------------------------------------------

createthreadA wait stringcat....
stringcat start....
stringcat end....
引用透传的参数被修改 xx y
-------------------------------------------------

getthreadresult wait stringcat....
getthreadresult detach threadid:
stringcat start....
8008
stringcat end....
xxyy,引用透传的参数没有被修改 x y
-------------------------------------------------

getthreadresult_lamba wait stringcat....
stringcat start....
stringcat end....
xxyy,引用透传的参数没有被修改 x y
-------------------------------------------------

请按任意键继续. . .

 

你可能感兴趣的:(多线程,C++,c,linux,2011)