« �����ʼ�(23) : ԭ���ֵ� | ������ҳ | �����ʼ�(24) : Lua State �������ݹ��� »

C �� coroutine ��

����ʵ����һ�� C �õ� coroutine ��.

���������������Ѿ������� C ����Աʵ�ֹ���, ����ͨ�� google ��������, ���ǽӿڲ���������, ���ǹ�������.

�� Windows ��, ���ǿ���ͨ�� fiber ��ʵ�� coroutine , �� posix ��, �и��򵥵�ѡ������ setcontext ��

�ҵ������������ģ�

��������Ҫһ�� asymmetric coroutine ���������ù� lua �� coroutine ��������ָ����ʲô��

���Σ��Ҳ�ϣ��ʹ�� coroutine ����̫���� stack ��С�����⡣����˵���û��� coroutine �ڿ���ʹ�õ� C stack ��С�����߳�һ���ࡣ

����Ҫ���� coroutine �ռ�ռ���ʲ�Ҫ̫�ߣ���Ϊ�ҿ��ܻ�ʹ����ǧ�� coroutine ���Ҳ�ϣ��ÿ����ռ�ð����ֽڵĶ�ջ��

��Ϊ�����ҵ�Ӧ�ó��ϣ�coroutine �л�����һ�̣�ʹ�õĶ�ջ�����ࣨ�����ܵ���һЩ��Ҫ������ջ�Ŀ⺯��������Щ�⺯���в����ᷢ���л��������ԣ����л���ʱ����ջ�����ǿ��Խ��ܵġ�coroutine �л�������Ƶ���������л��ɱ��ǿɿصġ�

���գ������ҵ�����ʵ��������Ҫ�������汾��

��Ȼ����ʱ����֧�� windows ����ʵ port �� windows ƽ̨�������ѣ�ֻ��Ҫ�� setcontext ���� api �ij� fiber �ļ��ɡ�

Comments

@Cinder �Ҳ²��Ǵ���contextʱ������һ���洢�ռ䣨S->Stack)��Ҳָ���˴�С���л�����Ӧ�������ĺ󣬻���S->Stack+size�ĵ�ַ��ʼʹ�������ռ䣬��������������save_stack��top-dummy��Ӧ���Ǹ�context�Ѿ�ʹ�õĿռ䣨dummy���ڸ�context������ʹ�õ�ջ�ռ䣩��
���˺ܾã�һֱû�����ף�_save_stack������S->stack,����S->stack�Ƕ��ϵ��ڴ���ַ��Ȼ�����õ�ʱ����_save_stack(struct coroutine *C, char *top) { // why does it work? char dummy = 0; assert(top - &dummy ���˺ܾã�һֱû�����ף�_save_stack������S->stack,����S->stack�Ƕ��ϵ��ڴ���ַ��Ȼ�����õ�ʱ����_save_stack(struct coroutine *C, char *top) { // why does it work? char dummy = 0; assert(top - &dummy <= STACK_SIZE); ������dummy��������ջ�ϵ������������ǻ�����һ����������ʵ��û�ܶ������δ��룬ϣ������ָ��һ��
��mainfunc����ǰ_co_delete�ˣ��ǽ���mainfunc���и�������swapcontext(C->ctx.uc_link������Ҳ���ͷ��ˣ���һ���������ⲻ�󣬶��ܼ��λ��߶��߳��£��϶������⡣
�ֲ��������������첽�ص���ֵ�� struct schedule *s; void work_done_cb(async_result_t *res, void *user_data) { async_result_t **resp = user_data; *resp = res; } void task_func(void *arg) { async_result_t *res = NULL; do_work_async(work_done_cb, &res); while(!res) { coroutine_yield(s); } // BUG: ���� work_done_cb �������ˣ����Ķ�ջ���ݻָ�����Ҳ�Ḳ�ǵ� work_done_cb �ж� res �ĸ�ֵ�������޷�ִ�е����� ... }
@bughoho �Ҿ�������Э�̵�����ԭ���������ˡ�����Э�̣�ֻ��ʹ��overlap io,�������������Dz�֧��block io.
Ĥ��
Ӧ�ÿ���ֱ���� libevent �ɡ� Python ���� gevent ʵ��Э�̣��ײ������õ�������
����һ����������: ��һ��Э���д������쳣�������쳣�������У���ʱ��δNtContinue����ִ�У�yield������һ��Э���л�����������
����Ϊ��������ʵ���Ǵ����ġ� ��Ϊջ�����Dz��ܿ��������ĵ�ַ�ģ�������������ָ����ջ�ϱ�����ָ��ʧЧ�� �� α�� char buf[64]; read_from_net(socket, buf); �ڴ˺����ﵼ��Э�̹��𣬵ȴ�io���ɲ����µ��Ȼ�������buf�ĵ�ַ��ԭ��malloc�����Ŀ飬�������Ѿ����������ã�����a��Ұ�ġ�
������˼������id�ظ����õĵط���~
ѧϰ�ˣ� �����и��ط���Э��id�Ĺ���ʵ���е��򵥣�id���޷����յġ������������ⲻ֪�Ƿ�������Ƶ������/����Э�̣������ڴ�й¶��
���ǽ���epoll�������񼤻�ʱ��ȡջ��һ��requist����ʱ�黹ջ��
��Ҳ����һ����������������ࡣ
��Ҳ����һ����������������ࡣ
��Ҳ����һ����������������ࡣ
���ǹ���������
��Ӧ���Ǵ���������������ʵ����
top - &dummy������ʲô��˼��û̫���ף���@cloud ������
�����ܺ����л�������ʱ�������Ѻ���ջ֡���������ģ���������main������һ��������schedule�ṹ�壬��stack���ڽṹ����һ�������������ˡ�ȷʵ��� ��������Ҫÿ��Э��ά��һ�������ģ���Ϊÿ��Э���Ѿ����Լ���stack�ˡ����ڳ���û�в�����ֻҪ��������context֮���л����ɣ�һ�����ڵ�ǰ��һ��������һ����
ò��ûɶ��ȥʵ��WIN32�汾�ģ��Ϳ���һ��Ȼ��������WIN fiber�İ汾����˵ֻ��Ҫ�滻�ӿڣ�����WINDOWS��CreateFiber(Ex)������ֱ�Ӷ�ȡ/�滻��ջ�ǰɣ�һʱ���о��޴����֡� ������������һ�£����˸����Գ��򣬺�����CreteFiberEx�Ļ���ֱ�Ӱ�commit���ñȽ�С������Ū�˸�32bytes����Ȼ��reservedŪ1M���൱�ھͻ��Լ����ݴ�Сȥ�����ߴ��ˣ����������������ύ��С���߹�������Ūһ��1M�����飬���Կ����ڴ����Լ����������򲢲������ֱ�������֪���Dz��ǺͲ���ϵͳ�й�ϵ�� ������������������main���ӣ���Դ������ջ���ƵIJ��ֶ������ˣ���Ϊÿһ����ջ���ᡰ�Զ����������ݡ��������Ͳ�֪���Dz���֧�ִ�����������ʱû���������ӡ� PS����������һ��commit > reserved�IJ���Ҳ�������У�����΢��������������ͦ�����ˡ���
@plain ������
һ�����ʣ������ڲ�ͬ���߳���ʹ��coroutine_resume����
���Dz��Ǹ�golang������goroutingһ��һ���ģ�
c coroutine ��ʹ���� swapcontext ������gdb coredump��ʱ�� ò���޷��鿴������coroutine��ջ ֻ�ܿ����л������ĺ���ջ�� �Ҳ鿴�˺�Щ���ϣ�����ò���޷������� �Ʒ���������������
@Cloud hi, �Ӵ�Э�̲���, ������һ������coroutine��, �����ڸ���coroutine֮�乲��sys/queue.h���Ķ�������Ϣͨ��, ��������ʱ��ʾ�ϴ���.�ɷ�ָ��һ��.
@dannoy @Cloud �����������ˡ� ����Ϊջ��ʹ�õ�malloc�����Ŀռ䡣 ԭ����ÿ�ο����������õ���ջ�Ŀռ䡣
@Cloud лл�ظ��� �����Լ���ʧ�����൱Ȼ�İ�makecontext���ĺ���������C->func,��ʵ��mainfunc @Genius ����ʱ��stack��S->stack,ÿ��������ǰ�ָ�����ǰ������ջ
@dannoy ���� man makecontext On architectures where int and pointer types are the same size (e.g., x86-32, where both types are 32 bits), you may be able to get away with passing pointers as arguments to makecontext() following argc. However, doing this is not guaranteed to be portable, is undefined according to the standards, and won't work on architectures where pointers are larger than ints. Nevertheless, starting with version 2.8, glibc makes some changes to makecontext(3), to permit this on some 64-bit architectures (e.g., x86-64).
@Cloud ��һ����������һ�£�line 135�Ĵ��룺 makecontext(&C->ctx, (void (*)(void)) mainfunc, 2, (uint32_t)ptr, (uint32_t)(ptr>>32)); 1��Ϊʲô��������Sָ����ȥ������Ϊ���е�ϵͳ��64bit���� 2��Ϊʲôû�п���������ud�أ���������������ȷ�ģ��ܽ�һ��ԭ�������ҰѴ������д�����Ϊ���´���Ҳ���������У� uintptr_t ptr2 = (uintptr_t)C->ud; makecontext(&C->ctx, (void (*)(void)) mainfunc, 4, ptr, ptr>>32,ptr2, ptr2>>32); �����Ҳ²�ԭ���Ĵ���Ҳ����ij�ֻ��������ڶ��������ģ���ָ�̡� лл��
�ܾ����Ǹ�_save_stack�����������⣺ �����ڵ�153�У�if�������� 1.�ӵ���coroutine_yield��_save_stack����������ʹ�õ�ջ����C->stack�ɣ�Ҳ����˵free��������ʱ�������ռ����ڱ�ʹ���У� 2.����ֱ�Ӹ�C->stackָ������ô��esp ebp�ȼĴ�����û���أ�ջ����û�ġ������ں���ʹ�õ���ʵ��Ȼ��֮ǰ�����Ŀռ䣬swapcontext����������������Ҳ�ǡ�DZ�ڵ�BUG ! ��¥�����Ժ����ĸ÷�֧����
�ðѣ���ֻĤ���¡�
��������Ĥ��
140Ԫ�Ļ���DDR3 1600Ƶ�ʵģ�1333��Ƶ�ʸ��ӱ����ء�
1����co-routine, ƽ��ÿ��64K��ջ�� �Ѿ��Ǻܴ��Ķ�ջ�ˣ�����640�ס�����4G��PC ddr3�ڴ���140Ԫ���ң� �������ڴ����ܹ�һ�㣬���ǹ���̫�ࡣ :D
@David Xu ��ȷ, �� 64bit ϵͳ��, coroutine ռ�õĶ�ջ�ڴ��Dz�����̫������. Ӧ�����Ҷ�����. �������м��ٸ�ʵ��, �� 10 �����ҵ� os thread �ϵ���. (���ȵ�λ��ʵ���ڵ�һ����������) ÿ��ʵ������Ҫ��ʮ�� coroutine. �������������򼶵� coroutine ����.
��64λϵͳ���ջ�����Ĵ�����co-routine�Ƚ϶࣬����������ջ�ڴ��ռ������Ĵ󣬲�һ�����кܴ���Ӱ�졣Ϊʲô�أ���Ϊ�����뵽���������ڴ棬ֻҪ��ʵ�ʲ�ȥ����(touch)��Щ�ڴ棬����mmap������ջ������һ��û��Ҫ��memset()��0,ʵ���ڴ����󽫰�����ִ��ʱ��������������������ʵ�������ڴ���������Ҳ������libc��Ƕ�������ĺ�����Ҳ��ʵ�ʲ�������K��ջ������
Ϊ�˲��Զ�ջ�Ƿ�������������co-routine�Ķ�ջ̫С�ˣ������ķ�ʽ���ڴ�ͨ��mmap()���룬Ȼ�������뵽�������ڴ��Ŀ�ͷ������mprotect��������������Ϊ���������ܶ�д������������ջ�Ӹߵ�ַ���͵�ַ�ǵ�ʱ����������̫�������������������ڴ治�ɶ�д���������Ͼ�segment fault���������ڼ������������⡣�����߳̿�libthr�Ͼ����������ġ� ��������������С��һ��guard page (4096�ֽ� ): ���ܹ�Ҫ�����ľ��� guard_page + stack_size. p = (char *)mmap(guard_page+stack_size). Ȼ�� mprotect(p, 4096, PROT_NONE); return (p+4096);
@cloud ��֪���������Բ��ԣ�������׼��һ���µ�co-routine,������makecontext�����Ƚ���һ����ʼ�������ġ�����ԭ���������ģ� void makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...); Ҳ���������Դ���һ���µ����ں�����ַ���Լ�argc���������������ں���������ucp��ָ����ucontext_t������getcontext�������õģ�ûʲô���ɣ�����Ϊ�˵õ�һ�������ļĴ���״̬���ݣ�������������������Ȼ������������ucontext����uc_stack��������������co-routine���µĶ�ջ�� ���磺 ucp->uc_stack.ss_size = 4096; ucp->uc_stack.ss_sp = my_stack_memory�� Ȼ������makecontext. makecontext����Ϊ�����úû������صĶ�ջָ�룺 ��������ss_size+ss_sp����x86�ϣ���Ȼ�������͵�ַ����һЩ������ ��֮��������һ�������ij�ʼ�������ģ�����ָ���������ĺ����� ���ԣ��㴴��һ��co-routine�����Ķ�ջ�ǿ���Ԥ�ȹ̶���С�ġ� ������˵�Ŀ������ҾͲ��˽��ˡ� ��FreeBSD�������Բο�libc����makecontext��ʵ�֣� /usr/src/lib/libc/i386/gen/makecontext.c Ȼ������ʹ��setjmp+longjmp.
@David Xu ����ʵ����һ�� longjmp ����. �����л���ջ���ȽϷ���. ��ʵ�����ǿ������̵�. copy stack �Ŀ���Ҳ�ܴ�. �������ٿ���������. ����Ҫ����ʵ�ִ����� coroutine, ���ǻ״̬�IJ�����. ���Բ�ϣ��ÿ�� coroutine ��ռ��̫���ڴ�.
ϣ����û����������ֻ���˼����ӡ��Ҿ�������Ҫ����������������Ŀǰ��֪��setcontext��getcontext����ϵͳ���á������Ƚϴ󡣽����㻹����setjmp+longjmp. setcontext��getcontext��������ƫ��֧��ʵʱ��ռ��ʽ�ģ����������ı��涼��ͨ���ں˵��á�Ŀǰ���������ɵĸ���ָ��Ժ�������Ϊ�߽磬���㴦����״̬�����纯�����ö����ڣ����������ַ�ʵʱ���ȵ�co-routine��setjmp+longjmp�Ϳ����ˡ�lua�õ����㵥Ԫ������setjmp�Ѿ����˱�Ҫ��״̬�ֱ��棬���ⲻ���� �����þò�������֪�����������ˡ�
��֪��¥���Ƿ�֪��gnupth��Ŀ�����ǵ���Ŀ����ʹ������gnupth����ʵ����coroutine���������������ĺô����������ʵ��������ã�����ֱ���л�����һ��coroutineִ�С�
�����ķ�ʽ, ������ȫ�ֱ���ΪЭ�̵Ķ�ջ����(���õ�ַ), Э���л���������ȫ�ֱ���ʱ��������. ͨ���ļ�����Э��δ����, ����ջ��ַ��Ч.
��Ȼcoroutine��ʱ�ܷ���,���Ҿ�������ģʽ���DZ�����,������������ģʽ��������,ͬ���ܹ�ʵ������.
Ĥ��
ɳ��
ɳ��

Post a comment

�������������ص������뵽�����Ա�