关于异步的一些思考2

关于异步的一些思考2

最近一直忙着写垃圾代码了,好久没静下心来思考点东西了。期间用node.js写了点小玩意练了下手,回来看看自己写的那篇关于异步的一些思考,感觉有点东西当时想的不是很准确,有必要再写篇文章,下面的代码纯属手写,懒得开VS调了...

1.lambda
有了lambda,就有了闭包,有了lambda也就可以很容易的实现bind的各种功能。比如说吧,有一个函数,声明是这样的:

int foo(int a,double b);

用bind的话,可以给他直接绑定变量,比如:

//前面有两个变量x和y分别为int和double,略去不写
std::function<int(void)> func = std::bind(foo, x, y);

用lambda的话:

std::function<int(void)> func = [x,y]()->int{return foo(x, y);};

如果要求奇葩点,要调换两个参数的位置,用bind这么写:

std::function<int(double,int)> func = std::bind(foo, std::placeholders::_2, std::placeholders::_1);

这样返回的函数对象的参数就是两个参数的位置调换了。如果用lambda:

std::function<int(double,int)> func = [](double b, int a)->int{return foo(a, b);};

或者只绑定一个参数:

std::function<int(double)> func = std::bind(foo, x, std::placeholders::_1);

lambda:

std::function<int(double)> func = [x](double b)->int{return foo(x,b);};

所以仔细想下,有了lambda,bind真的意义不大了,C++11里面加了bind或许有啥特殊用处我还没了解,或者只是为了兼容吧,比如asio的placeholder,应该就只能用bind吧...

2.CPS变换
一开始以为CPS跟异步只是有点关系,后来发现如果不用啥coroutine库或者async.js这样的库,代码里面的cps变换简直多到让人蛋碎...而且这玩意有传染性..只要一个操作是异步的,需要一个回调来处理结果,那得到结果之后的代码只能在回调里面,然后里面再接着来一个异步操作...于是就这么一层层的嵌套下去了。比如说:

app.get('/',function()
{
    //do something..
    //要到数据库查点东西..
    db.get(function(docs)
    {
        //遍历结果
        docs.forEach(function(doc)
        {
            //....
        });
    });
});

这种代码能看???用bind也是一个样,只是把回调函数单独抽出去了而已,本质上跟这个一个样..如果循环里面再嵌套一个异步操作..简直无法可想,很多异步还不能同时发起多个读取或写入操作,必须等前一个完成,比如asio(nodejs能不能我还真不太清楚),这是你只能把循环拆分开来放到各个回调里面。比如说吧,我要把一个vector里面的东西循环发送出去(下面代码只是表达意思):

// 前面有个vec为std::vector<int>类型,handle_write为回调函数,没代码
foreach(auto x in vec)
{
    boost::asio::async_write(sock, boost::asio::buffer(&x,sizeof(int)), handle_write);
}

这是严重错误的,你在发起了一次async_write之后,没有等返回(handle_write被调用)就可能循环回来发第二次了,之前的asio学习笔记就说过了。所以你只能改成这样:

void handle_write(std::vector<int>::iterator it)   //省略了错误判断
{
    ++it;
    if (it == vec.end())
    {
        //循环完了处理后事
        return;
    }
    boost::asio::async_write(sock, boost::asio::buffer(&(*it),sizeof(int)), std::bind(handle_write,it));
}

// 在xx函数中..
....
std::vector<int>::iterator it = vec.begin();
boost::asio::async_write(sock, boost::asio::buffer(&(*it),sizeof(int)), std::bind(handle_write,it));
.....

就特么一个循环都要写成这样,你让我如何不蛋疼..你如果把上面的std::bind和handle_write换成lambda的表示方式,就能看出来他跟nodejs的那个一模一样。当然你可以用coroutine把他搞得像看起来同步的那样..不过C++的coroutine(也就是boost.coroutine和asio的那个coroutine了)也是各种蛋疼。

先写这些了,以后想到啥再补充..话说直接在blog里面敲代码真是恶心啊,终于知道了那些用记事本写代码的...真的是在用绳命装X啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值