一、协程的由来
从IO同步和异步的优缺点分析如下:
IO同步优点就是sockfd管理方便,操作逻辑清晰;缺点是程序依赖epoll_wait的循环响应速度,程序性能差。
IO异步优点就是子模块好规划,程序性能高;缺点就是逻辑理解有点难度,还会出现多个线程共用一个sockfd,此时需要避免在IO操作时,出现sockfd出现关闭或其它异常。
有没有一种方式,同步的方式实现了异步的性能呢?那就是下文所说的协程。
二、协程切换的核心
协程切换核心就是yield(让出)与resume(恢复)来实现协程上下文切换,实现有以下3种方法。
(1)longjmp和setjmp
(2)ucontext
(3)汇编实现跳转
本文使用第三种汇编实现,yied = switch(a,b),resume = switch(b,a),根据不同的处理器的汇编指令实现switch的操作,比如x64_86如下。
_asm__(
" .text \n"
" .p2align 4,,15 \n"
".globl _switch \n"
".globl __switch \n"
"_switch: \n"
"__switch: \n"
" movq %rsp, 0(%rsi) # 从rsp存到rsi寄存器 \n"
" movq %rbp, 8(%rsi) # 移动8个字节,一个指针是8个字节 \n"
" movq (%rsp), %rax # save insn_pointer \n"
" movq %rax, 16(%rsi) \n"
" movq %rbx, 24(%rsi) # save rbx,r12-r15 \n"
" movq %r12, 32(%rsi) \n"
" movq %r13, 40(%rsi) \n"
" movq %r14, 48(%rsi) \n"
" movq %r15, 56(%rsi) \n"
" movq 56(%rdi), %r15 \n"
" movq 48(%rdi), %r14 \n"
" movq 40(%rdi), %r13 # restore rbx,r12-r15 \n"