多线程基础3-----<future>

来源:互联网 发布:淘宝开店铺要交押金吗 编辑:程序博客网 时间:2024/06/11 04:47


C++11线程通信:<future>
首先,As everyone knows,进程是系统资源的分配的基本单位,线程是执行的基本单位
同一进程的线程公用进程空间,如此大大简化了线程间的通信,如可以直接用全局变量来进行通信,但这样也带来了很大的troble(资源竞争),那么<future>应运而生(当然<future>只是解决手段之一)


模板类----future<>


函数async():

unspecified policy (1)
template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>

    async (Fn&& fn, Args&&... args);

specific policy (2)
template <class Fn, class... Args>
  future<typename result_of<Fn(Args...)>::type>

    async (launch policy, Fn&& fn, Args&&... args);


模板类----future<>

构造函数:

default (1)

future() noexcept;
copy [deleted] (2)
future (const future&) = delete;
move (3)

future (future&& x) noexcept;


其他成员函数:

future::operator=//Move-assign future (public member function 

future::get//Get value (public member function 

share//Get shared future (public member function )//转换得到一个shared_future<>的对象

obj.share实例:

#include<iostream>#include<thread>#include<future>int f(){return 12;}int main(){std::future<int> fu = std::async(f);std::shared_future<int> sht_fu = fu.share();try{std::cout<<fu.get();sht_fu.get();}catch (std::future_error &error){std::cout << "fu对象复用错误" << std::endl;}return 0;}
以上结果证明share函数以std::move()方式传递

 valid //Check for valid shared state (public member function )
      wait //Wait for ready (public member function )
        wait_for //Wait for ready during time span (public member function )
wait_until//Wait for ready until time point (public member function )

//简单的应用<future>#include<iostream>#include<future>#include<thread>#include<cstdlib>int fun(int mm){std::cout << "线程先运行,出结果传给了fu" << std::endl;return ++mm;}int main(){std::future<int> fu = std::async(std::launch::async|std::launch::deferred,fun,12);//在此用定义一个future//关于std::async()参数:第一个参数决定是否采用多线程//std::launch::async决定future对象获取int值采用多线程(创建子线程)//std::launch::deferred不采用多线程,而是在fu.get()时在同一线程调用fun函数//std::launch::async|std::launch::deferred即为函数的默认调用形式://std::future<int> fu = std::async(fun,12);_sleep(10000);//这里来一个休眠;根据运行结果可以证明一点://1.在笔者机子上运行结果 :"线程先运行,出结果传给了fu"‘\n’13//2.由此可以证明:async函数以多线程执行,且异步于主线程std::cout << fu.get()<<std::endl;//切记future对象只能调用一次成员函数get();return 0;}//由上诉的结论可知,总结future<>对象://future像是对未来的一个预约//通俗的讲://老板对下属说:我要看公司20年来的发展趋势,你准备一下-----std::future<int> fu = std::async(fun,12);//然后在不定时间后//老板向下属要所需材料://下属立马把老板吩咐需要的东西提交给老板------std::async()函数第一个参数是std::launch::async时//下属此时去收集老板所需要的材料:老板等待下属收集材料-----std::async()函数第一个参数是std::launch::deferred时



模板类-----promise<>:

成员函数:


default (1) promise();
with allocator (2) template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc);
copy [deleted] (3) promise (const promise&) = delete;
move (4)
promise (promise&& x) noexcept

(destructor) Destroy promise (public member function )
operator= Move-assign promise (public member function )
get_future Get future (public member function )
set_value Set value (public member function )//履行承若,设置promise值

swap Swap shared states (public member function )

以下是极端错误的处理函数(你出错,我断后)

::如在线程结束时promise对象还未实现承若(obj.set_value(parameter))

set_exception Setexception (public member function )
set_value_at_thread_exitSet value at thread exit (public member function )
set_exception_at_thread_exit Set exception at thread exit (public member function )

#include<iostream>#include<thread>#include<future>void f(std::future<int> &ff){std::cout<< ff.get();}int main(){std::promise<int> prom;std::future<int> fu = prom.get_future();std::thread t(f,std::ref(fu));prom.set_value(20);t.join();return 0;}

再来一个双向通信 的二刀流:

#include<iostream>#include<thread>#include<future>int f(std::future<int> &ff){return ff.get();}int main(){std::promise<int> prom;std::future<int> fu = prom.get_future();std::future<int> fu2= std::async(f,std::ref(fu));prom.set_value(20);std::cout << fu2.get();return 0;}

模板对象:packaged_task<>

packaged_task的两个基本特性:

1.任务包的构造函数只有一个参数;

2.任务包可以与future<>对象建立异步联系

成员函数:

default (1) packaged_task() 

noexcept;initialization (2) template <class Fn>explicit packaged_task (Fn&& fn);

with allocator (3) template <class Fn, class Alloc>explicit packaged_task (allocator_arg_t aa, const Alloc& alloc, Fn&& fn);

copy [deleted](4) packaged_task (const packaged_task&) = delete;

move(5) packaged_task (packaged_task&& x) noexcept;

(destructor) //Destroy packaged task (public member function )

operator= //Move-assign packaged_task (public member function )

valid //Check for valid shared state (public member function )

get_future //Get future (public member function )

operator() //Call stored task (public member function )

make_ready_at_thread_exit //Call stored task and make ready at thread exit (public member function )

reset //Reset task (public member function )//更新future对象的状态,使之可以重复调用obj.get();

swap //Swap packaged_task (public member function )

//其实packaged_task字面意思就是将任务打包封装起来//然后可以执行任务包或者传递任务包//笔者浅见:任务包的传递才是packaged_task存在的意义#include<iostream>#include<thread>#include<future>#include<chrono>int pack_task(int m){//计算阶乘//<return>返回阶乘结果</return>int ret=1;for (; m > 1; m--)ret *= m;return ret;}int main(){std::packaged_task<int(int)> task(pack_task);//封装任务包std::future<int> ret_fu = task.get_future();//建立异步连接std::thread t(std::move(task),5);//启动任务包。t.join();std::cout << ret_fu.get();//用future对象获取返回值//上诉的异步通信,可以用前面说过的async(std::launch::async,pack_task,5);来进行替代达到同样的效果return 0;}


模板对象:shared_future<>

当线程间存在多线程交互通信是使用shared_future<>通信相对比较方便


成员函数:

default (1)shared_future() noexcept;
copy (2) shared_future (const shared_future& x);
move (3) shared_future (shared_future&& x) noexcept;
move from future (4) shared_future (future<T>&& x) noexcept;

                                                                                                              

(destructor)//Destroy shared_future (public member function )
operator= //Assign shared future (public member function )
get //Get value (public member function )
valid //Check for valid shared state (public member function )
wait //Wait for ready (public member function )
wait_for //Wait for ready during time span (public member function )
wait_until //Wait for ready until time point (public member function )

#include<iostream>#include<thread>#include<future>#include<algorithm>#include<vector>#include<mutex>#include<iomanip>std::mutex mu;void threadFun(std::shared_future<int> &sf){std::lock_guard<std::mutex> lock(mu);//显存互斥(标准输出流)std::cout << "Thread_ID: " << std::setw(6)<<std::left<<std::this_thread::get_id();std::cout << "\t\t" << sf.get() << std::endl;}int main(){std::vector<std::thread> v;std::promise<int> prom;std::shared_future<int> sh_fu = prom.get_future();for (int i=0; i < 10; i++){std::thread t(threadFun, std::ref(sh_fu));v.push_back(std::move(t));}prom.set_value(20);//for (int i=0; i < 10; i++)//{//v.at(i).join();//}std::for_each(v.begin(),v.end(),[&](std::thread &i){i.join(); });return 0;}


<笔者才疏学浅,如有误笔,敬请指正>

<至于future里面的错误处理机制,读者感兴趣可以自行研究<exception>>




原创粉丝点击