解开ucontext函数族的魔法魅力-Linux协程艺术 (解开石头的谜)
操作系统提供了许多弱小的系统调用和库函数,其中之一是ucontext函数族。这个函数族准许开发者控制程序的口头高低文,包括寄存器形态,以便成功一些初级的操作,比如协程调度。本文将深化解析ucontext函数族,从寄存器形态开局引见,而后剖析每个函数的详细实现代码,最后经过示例展现如何经常使用ucontext成功协程调度。
寄存器
无了解ucontext函数族之前,让咱们先来了解一下寄存器形态。在Linux中,寄存器是CPU中的一组不凡的存储单元,它们用于存储程序口头环节中的数据和指令。ucontext函数族中的函数可以用来保留和复原这些寄存器形态,成功高低文切换。
经常出现的寄存器包括:
ucontext族
ucontext函数族包括以下函数:
这些函数准许咱们保留和复原程序的口头形态,以及在不同高低文之间切换,这关于成功协程调度十分有用。ucontext函数族的成功通常依赖于操作系统内核的支持。它们经过setcontext和swapcontext等系统调用来成功高低文切换。内核保养了一个进程高低文的数据结构,并依据须要切换到不同的高低文。
要深化了解ucontext函数族的详细成功,你可以检查内核源代码。不同版本的Linux内核或者会有不同的成功细节,因此你须要检查与你的内核版本婚配的代码。通常,相关的代码位于内核的arch目录下,比如arch/x86/kernel/。
ucontext_t结构体是一个用于示意程序高低文的结构体,它蕴含了一些关键的寄存器形态和信息,准许在不同的口头高低文之间启动切换。
typedefstructucontext{unsignedlonguc_flags;//标记位,用于标识高低文的形态structucontext*uc_link;//指向下一个高低文的指针,通常是在切换高低文后前往的高低文stack_tuc_stack;//蕴含堆栈信息的结构,形容了高低文的堆栈mcontext_tuc_mcontext;//蕴含机器寄存器形态的结构...//其余平台特定的字段}ucontext_t;
ucontext_t结构体的详细成功或者会因操作系统和体系结构而异。
经常使用ucontext成功协程调度
#include<ucontext.h>#include<stdio.h>ucontext_tcontext1,context2;//申明两个高低文对象//协程1的函数voidcoroutine1(){printf("Coroutine1n");//打印信息swapcontext(&context1,&context2);//切换高低文到协程2printf("Coroutine1agnn");//再次打印信息swapcontext(&context1,&context2);//切换高低文回协程2}//协程2的函数voidcoroutine2(){printf("Coroutine2n");//打印信息swapcontext(&context2,&context1);//切换高低文回协程1printf("Coroutine2againn");//再次打印信息}intmain(){getcontext(&context1);//失掉以后高低文并存储到context1context1.uc_stack.ss_sp=malloc(8192);//为协程1调配堆栈context1.uc_stack.ss_size=8192;//设置堆栈大小context1.uc_link=NULL;//设置高低文链接为空makecontext(&context1,coroutine1,0);//创立协程1的高低文,关联coroutine1函数getcontext(&context2);//失掉以后高低文并存储到context2context2.uc_stack.ss_sp=malloc(8192);//为协程2调配堆栈context2.uc_stack.ss_size=8192;//设置堆栈大小context2.uc_link=NULL;//设置高低文链接为空makecontext(&context2,coroutine2,0);//创立协程2的高低文,关联coroutine2函数swapcontext(&context1,&context2);//切换到协程1的高低文口头,协程切换出当初这里free(context1.uc_stack.ss_sp);//监禁协程1的堆栈free(context2.uc_stack.ss_sp);//监禁协程2的堆栈return0;}
这段代码成功了两个协程(coroutine1和coroutine2)之间的切换,它们在不同的高低文中运转。getcontext用于失掉以后高低文,makecontext用于创立协程的高低文,并将它们与对应的函数关联。swapcontext用于切换高低文,从一个协程切换到另一个。在main函数中,首先切换到协程1的高低文口头,而后再次切换回协程2,最终监禁堆栈内存。
如何追踪linux指针函数
以下方法适合于arm平台,其它平台类似。 查看指针函数实际调用了哪个函数:在内核中放置打印函数,打印出函数的地址。 2. arm-linux-addr2line 0xXXXXXXXX -e vmlinux -f查看谁调用了这个函数:1. 在被调用函数里放置打印函数,加参数:__builtin_return_address(0)2. arm-linux-addr2line 0xXXXXXXXX -e vmlinux -f
简述linux下,从socket写入和读取的函数,read/write和send/recv函数的含义并解释其接口意义?简答题
Ssize_twrite(int fd,const void *buf,size_t nbytes); write的返回值大于0,表示写了部分数据或者是全部的数据,这样用一个while循环不断的写入数据,但是循环过程中的buf参数和nbytes参数是我们自己来更新的,返回值小于0,此时出错了,需要根据错误类型进行相应的处理Ssize_tread(int fd,void *buf,size_t nbyte)Read函数是负责从fd中读取内容,当读取成功时,read返回实际读取到的字节数,如果返回值是0,表示已经读取到文件的结束了,小于0表示是读取错误。 Recv函数和send函数Recv函数和read函数提供了read和write函数一样的功能,不同的是他们提供了四个参数。 Intrecv(int fd,void *buf,int len,int flags)Intsend(int fd,void *buf,int len,int flags)前面的三个参数和read、write函数是一样的。 第四个参数可以是0或者是一下组合:MSG_DONTROUTE:不查找表是send函数使用的标志,这个标志告诉IP,目的主机在本地网络上,没有必要查找表,这个标志一般用在网络诊断和路由程序里面。 MSG_OOB:接受或者发生带外数据表示可以接收和发送带外数据。 MSG_PEEK:查看数据,并不从系统缓冲区移走数据是recv函数使用的标志,表示只是从系统缓冲区中读取内容,而不清楚系统缓冲区的内容。 这样在下次读取的时候,依然是一样的内容,一般在有过个进程读写数据的时候使用这个标志。 MSG_WAITALL:等待所有数据是recv函数的使用标志,表示等到所有的信息到达时才返回,使用这个标志的时候,recv返回一直阻塞,直到指定的条件满足时,或者是发生了错误。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。