协程的多线程切换
来源:互联网 发布:p2psearcher百度软件 编辑:程序博客网 时间:2024/06/10 08:44
http://www.thinksaas.cn/group/topic/347319/
我们知道,在一个基于协程的应用程序中,可能会产生数以千记的协程,所有这些协程,会有一个的调度器来统一调度。 另外我们知道,高性能的程序首要注意的就是避免程序阻塞。那么,在以协程为最小运行单位的程序中,同样也需要确保这一点,即每一个协程都不能发生阻塞。因为只要某一个协程发生了阻塞,那么整个调度器就阻塞住了,后续等待的协程得不到运行,整个程序此时也将死翘翘了。那么,如果需要保证任意一个协程都不阻塞,该怎么做呢?
通常,协程主调度器管理着本线程中所有的协程,并依次调度这些协程运行,在一个协程执行完之后,需要将执行权限交给调度器,即进行 yield 操作,以便调度器能够调度后续等待运行的协程。如果在某个协程内,含有阻塞操作,如打开数据库连接:
exe_non_block1();open_db_conn(...);exe_non_block2();
如上边代码所示,先执行了exe_non_block1
, 然后打开一个数据库连接,之后再执行exe_non_block2
, 如果对这段代码不做任何处理,倘若打开数据库连接需要耗时很多,那么在这期间,整个程序就阻塞住了,这种情况是绝对不能容许的。怎么解决呢?
我们看,先执行了exe_non_block2
, 然后执行open_db_conn
, 如果能够把open_db_conn
这个函数调用放到其他的线程中去执行,同时本协程yield
,交出执行权限;之后,当open_db_conn
在其他线程执行完毕时,再切换到这个协程,并且能够接着exe_non_block2
继续执行,那么我们就可以解决上边提出的问题, 保证整个主调度器不会阻塞,即便某一个协程中需要进行阻塞操作,我们也可以把这段会阻塞的代码放到其他线程中取执行,等执行完成后,再切换回来。换句话说,就是需要协程有这样的特性:
能够按照代码顺序依次在多个线程中执行 那么,协程有这样的特性吗? 很幸运,协程是有的,因为在每次交出执行权限(即yield
)时,都会保留栈信息。请看下边的实验代码(multi_thread_switch.c):
#include"../libcoro/coro.h"#include <pthread.h>#include <stdio.h>#include <stdlib.h>coro_context main_ctx;coro_context parallel_ctx;coro_context ctxa;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;coro_context *current_main_ctx;void parallel_coro_func(void *arg);void* thread_main_func(void* arg){ pthread_t pid = pthread_self(); printf("subthread:%lun", pid); void *stk = malloc(8192); coro_create(¶llel_ctx, ¶llel_coro_func, NULL, stk, 8192); coro_context ctx; coro_transfer(&ctx, ¶llel_ctx);}void parallel_coro_func(void *arg){ while(1) {pthread_mutex_lock(&mutex); current_main_ctx = ¶llel_ctx; coro_transfer(¶llel_ctx, &ctxa);pthread_mutex_unlock(&mutex);usleep(1000*10);}}void coro_funca(void *arg) { pthread_t ptid; while(1) { int c = 0; printf("----------start loop---------n");++c; ptid = pthread_self(); printf("coro_funca, thread: %lu, count:%dn", ptid, c); coro_transfer(&ctxa, current_main_ctx);++c; ptid = pthread_self(); printf("coro_funca, thread: %lu, count:%dn", ptid, c); coro_transfer(&ctxa, current_main_ctx);++c; ptid = pthread_self(); printf("coro_funca, thread: %lu, count:%dn", ptid, c); coro_transfer(&ctxa, current_main_ctx);++c; ptid = pthread_self(); printf("coro_funca, thread: %lu, count:%dn", ptid, c); coro_transfer(&ctxa, current_main_ctx); printf("----------end loop---------nn");}}int main(void){ void *stka = malloc(8192); coro_create(&ctxa, &coro_funca, NULL, stka, 8192); pthread_t ptid1; if(pthread_create(&ptid1, NULL, &thread_main_func, NULL) != 0) {exit(0);} pthread_t mpid = pthread_self(); printf("main thread:%lun", mpid); while(1) {pthread_mutex_lock(&mutex); current_main_ctx = &main_ctx; coro_transfer(&main_ctx, &ctxa);pthread_mutex_unlock(&mutex);usleep(1000*10);} return 0;}
-EOF-
- 协程的多线程切换
- 协程的多线程切换
- Java多线程的上下文切换
- IOCP GetQueuedCompletionStatus多线程切换的不确定性
- 多线程的代价及上下文切换
- 同一进程的多线程之间的切换时间粗侧
- 多线程上下文切换
- java多线程状态切换
- rxjava多线程切换
- 多线程系列 - 上下文切换
- 多线程上下文切换
- Java多线程--上下文切换
- 多线程--上下文切换
- 多线程下切换输入法导致程序假死的问题
- 【Java多线程 锁优化】锁的三种状态切换
- 【Swoole基础】Linux的多线程切换和多进程的切换
- 多线程中两个必要的开销:线程的创建、上下文切换 上下文切换
- state-threads的协程切换
- cocos2d-x起点
- BestCoder_Pairs
- Win7 X64 vs2008 崩溃问题
- CentOS 鸟哥 第4-5章
- hdu 3032 Nim or not Nim? 博弈论,,,网上搜的题解让我大开眼界,原来还可以这样A题
- 协程的多线程切换
- 黑马程序员_Java的反射机制
- malloc释放的想到的问题
- Mysql跨表更新
- 什么是启耘BOX?
- eclipse快捷键
- Apache修改web根目录
- poj1087 floyd+二分图最大匹配
- 拜拜了,浮动布局-基于display:inline-block的列表布局