Linux C/C++ 学习日记(37):协程(六):总结
注:该文用于个人学习记录和知识交流,如有不足,欢迎指点。
一、recv/send 同步的。
调用,就执行一次(不管有没有数据)
如果是阻塞的,就阻塞在这里等到有数据就取走(程序卡在这,如果是多线程:CPU会释放给别的线程使用)
如果是非阻塞的,去查看,没数据就直接返回了
二、nty_recv / nty_send 异步的
反正我就一定要取走一次数据:
如果没数据,我就加入epoll监听,然后切换到别的协程函数干别的事情,等到epoll响应了,我在回来取走。
tips:
如果不设置超时,形式上来看,nty_recv就相当于是阻塞的recv(实际上内部用的是非阻塞recv,这样才能够切换),如果一直没收到数据,那么就一直不会切换回来,所以说形式上相当于阻塞的recv(区别在于阻塞的recv是线程阻塞,而nty_recv是协程阻塞)
三、总的来讲,协程就是仿照线程的用法。使用起来的形式跟线程一毛一样:
线程函数采用同步的编程方式
协程函数跟线程一样也采用同步的编程方式两者都有异步的性能,阻塞的话,CPU就被调度到别的 线程/协程 去执行
把多线程搞成多协程:
- 原来的线程函数里面的代码我都不用动,弄个hook,就可以直接把线程函数搞成协程函数了。把pthread_create搞成coroutine_create,创建的就是协程了。
- 这样下来,就可以用于IO密集型了(实现一fd一协程)
四、线程与协程两者的区别
1. CPU使用数量与切换:
多个协程是运行在一个线程上的,也就是只使用一个CPU,但是协程切换快(用户态)。
多个线程可以使用多个CPU,但是线程切换慢(内核态)。
2. 占用空间:
协程:KB级别,在高并发网络中,可实现1fd1协程
线程:MB级别(linux中为8MB),在高并发网络中,实现不了1fd1协程
3. 在IO密集型中
协程效率高于线程。
4. 在CPU密集型中
一般选择线程,且线程数一般为CPU的内核数,减少切换带来的开销。
