协程和异步

同步与异步

  在写我对协程的理解前,我觉得有必要先说明一下同步和异步之间的关系和区别。

同步

  可以给同步下这么一个定义:如果在调用某个函数结束的时候,就能拿到这个函数应该返回的结果,那么我们就称这个过程是同步的。在C++中,绝大部分的过程都是同步的,因为对于一个具体的函数而言,我们肯定是希望获得这个函数的结果再进入下一步的操作,举个例子,我想将用户传递给我的数据进行md5加密,再存入数据库中,其调用的过程肯定是先执行md5计算,再执行数据库存入过程。

string rtn = md5(data);
mysql_write(rtn);

  这样做是合情且合理的(废话),因为大部分情况下都需要等待函数执行并返回的结果,才能拿着这个结果进行下一步操作,那为什么还需要异步呢?

异步

  相对于同步而言,异步的定义:如果在函数返回的时候,不能立即得到想要的结果,而是需要在未来通过一定的手段得到,那么这个函数就是异步的。将上面的过程写成异步调用大概长这样:

async_md5(data, mysql_write());
//do other thing here

  在这个过程中,async_md5立即就能返回并继续向下执行其他的过程。在将来的某个时候async_md5完成了md5的计算,那么它将会调用我们注册的mysql_write()函数写入数据库中,这个过程就是异步写入。

  那么为什么需要异步?

  上面举了一个md5计算的例子,大家都知道md5计算是消耗CPU的,所以要执行完这个函数无论如何都是要经过一定的CPU运算量的。然而除了CPU消耗型的函数,还有一种情况是IO密集型的函数,这种情况下函数消耗的时间大部分都浪费在等待IO完成上了,实际的CPU占用率是很低的,也就是说程序会一直等在那里什么都不干,直到IO过程就绪。

  如果将异步的思想引入这里(具体如何实现呆会再分析),那么此时该进程就可以继续向下执行了,等到IO完成之后,会自动地异步调用mysql_write(),完成后续的写入过程。

  因此,异步适合在那些需要马上返回的场合(例如UI的主线程)等非阻塞场景下使用。总的来说就是,同步能保证顺序执行,但是容易被阻塞。而异步不容易被阻塞但是无法确定处理的顺序。

异步的实现

  想一想,如果要让你来实现一个最简单的异步过程会怎么做。最简单的办法

评论卡