C++ async task

  最近在搞Android 开发,里面多线程的使用比较频繁,java多线程接口很方便。 Thread, AysncTask, Handler 这些接口比起posix提供的pthread_create()等一系列接口方便很多,想到C++11也支持方便的多线程编程,最近java中AsyncTask用的比较多,于是学习了一下C++中的async task。

  

  C++ std::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);
  

      std::async() 的 fn 和 args 参数用来指定异步任务及其参数。另外,std::async() 返回一个 std::future 对象,通过该对象可以获取异步任务的值或异常(如果异步任务抛出了异常)。

  上面两组 std::async() 的不同之处是第一类 std::async 没有指定异步任务(即执行某一函数)的启动策略(launch policy),而第二类函数指定了启动策略,详见 std::launch 枚举类型,指定启动策略的函数的 policy 参数可以是 launch::async,launch::deferred,以及两者的按位或( | )。

  来一段代码学习一下:

 1 #include "stdafx.h"
 2 
 3 
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 
 7 #include <cmath>
 8 #include <chrono>
 9 #include <future>
10 #include <iostream>
11 
12 
13 int main(int argc, const char *argv[])
14 {
15     auto begin = std::chrono::steady_clock::now();
16 
17         //std::future<double> 
18     auto f(std::async(std::launch::async,[](int n){
19 std::cout << std::this_thread::get_id() 20 << " start computing..." << std::endl; 21 22 double ret = 0; 23 for (int i = 0; i <= n; i++) { 24 ret += std::sin(i); 25 } 26 27 std::cout << std::this_thread::get_id() 28 << " finished computing..." << std::endl; 29 return ret; 30 } 31 ,100000000)); 32 33 34 while(f.wait_for(std::chrono::seconds(1)) 35 != std::future_status::ready) { 36 std::cout << "task is running.../n"; 37 } 38 39 40 auto end = std::chrono::steady_clock::now(); 41 42 auto diff = end - begin; 43 44 std::cout << "async_task result: "<<f.get() << std::endl; 45 std::cout << std::chrono::duration <double, std::milli> (diff).count() << " ms" << std::endl; 46 47 return EXIT_SUCCESS; 48 }

运行结果:(VS2012,ubuntu14.04 使用的是gcc4.9.1 也可以毫无压力运行)

C++ async task

n 后问题

  n后问题,解决思路:假设每个皇后占一行(且第i个皇后放在第i – 1 行),依次去尝试下一个皇后该放在该行的哪一列

#include<iostream>
#include<cmath>
using namespace std ;
class queen
{
       public :
      
             queen (){};
             //queen(int row = -1, int col = -1) : m_row(row), m_col(col) {}
            
             void setRow( int row) { m_row = row ; }
             void setCol( int col) { m_col = col ; }
            
             int getCol() const {return m_col ; }
             int getRow() const {return m_row ; }
            
       private :
      
             int m_row;
             int m_col;
};

// curr : 当前的皇后序号(第几个皇后),该值也表明该皇后在第几行
void Queue( queen * nq , int curr , int *sum , int n )
{
       if ( curr == n )
      {
             for (int i = 0 ; i < n ; i ++)
            {
                   cout << nq [i ]. getCol()<< " " ;
            }
             cout <<endl ;
            (* sum )++;
            
             return ;
      }
       int i, j;
       for ( i = 0 ; i < n; i++) //  i 表示所有列,依次尝试放在每一列
       {
             for ( j = 0 ; j < curr; j++) // j 代表已经放下的皇后
             {
                   //if( abs(nq[j].getCol() - nq[i].getCol()) == abs(nq[j].getRow() - nq[i].getRow()) || nq[i].getCol() == nq[j].getCol())
                   if ( abs (nq [j ]. getCol() - i) == abs (nq [j ].getRow () - curr ) || nq [j ].getCol () == i)
                         break ;
            }
             if ( j == curr ) // 可以放下,和前 curr - 1 个皇后都不冲突
            {
                   nq[ curr ].setCol (i );
                   Queue (nq , curr + 1 , sum , n );
            }
      }
}

int nqueenP( int n)
{
       queen * nq = new queen [n ];
      

       for (int i = 0 ; i < n ; i ++)
      {
             nq[ i]. setRow (i );
             nq[ i]. setCol (0 );
      }
      
       int sum = 0 ;
      
       Queue (nq ,0 ,&sum ,n );
      
       return sum ;
}


int main()
{
       cout <<"8 Queue Result: " << nqueenP( 8 )<<endl ;
}