1.gitçå·¥ä½åç
2.libevent、码链libev框架介绍
3.Git从入门到精通(下篇)-4-git commit详解
4.自制处理器系列(一):一生一芯计划-预先学习阶段(P线)
5.wait(linux kernel 等待队列)
gitçå·¥ä½åç
gitçå·¥ä½æ»å ±ååå±ï¼å ¶ä¸ä¸å±æ¯å¨èªå·±æ¬å°ä¹å°±æ¯è¯´gitä»åºï¼å æ¬äºå·¥ä½ç®å½ãæååºåæ¬å°ä»åºãå·¥ä½ç®å½å°±æ¯æ们æ§è¡å½ä»¤git initæ¶æå¨çå°æ¹ï¼ä¹å°±æ¯æ们æ§è¡ä¸åæ件æä½çå°æ¹ï¼æååºåæ¬å°ä»åºé½æ¯å¨.gitç®å½ä¸ï¼å 为å®ä»¬åªæ¯ç¨æ¥åæ°æ®çãè¿ç¨ä»åºå¨ä¸å¿æå¡å¨ï¼ä¹å°±æ¯æ们å好工ä½ä¹åæ¨éå°è¿ç¨ä»åºï¼æè ä»è¿ç¨ä»åºæ´æ°ä¸æ¥ææ°ä»£ç å°æ¬å°ãGitæåå¨çé½æ¯ä¸ç³»åçæä»¶å¿«ç §ï¼ç¶ågit æ¥è·è¸ªè¿äºæä»¶å¿«ç §ï¼åç°åªä¸ªæä»¶å¿«ç §æååä»å°±ä¼æç¤ºä½ éè¦æ·»å å°æååºææ¯æ交å°æ¬å°ä»åºæ¥ä¿è¯ä½ çå·¥ä½ç®å½æ¯å¹²åçã
è¿ä¸ªè¦æä¹ç解å¢ï¼gitä¸çæ件æ两ç§ç¶æï¼ä¸ç§æ¯è¢«è·è¸ªçï¼ä¹å°±æ¯æ交å°æ¬å°ä»åºçæ件ï¼å 为æ¬å°ä»åºè¦ä¿ç®¡å®ä»¬å½ç¶è¦è·è¸ªä»ä»¬ï¼å¯¹ä»ä»¬è´è´£ï¼è¿æä¸ç§å°±æ¯æªè¢«è·è¸ªçãé£ä¹å½æ们添å æ°çæ件æ¶ï¼ä»ä¸æ¯è¢«è·è¸ªçï¼å 为æ¬å°ä»åºéé¢æ²¡æè¿ä¸ªæ件ï¼ä»æ¯å¤æ¥çï¼æ¬å°ä»åºç®åè¿ä¸éè¦å¯¹ä»ä»¬è´è´£ãä½æ¯å¦ææ¯å¯¹ä»åºå·²ç»åå¨çæ件è¿è¡ä¿®æ¹ï¼é£ä¹è¿äºæ件就æ¯è¢«è·è¸ªçæ件ï¼å°±å¯ä»¥éè¿git statusæ¥çä»ä»¬çç¶ææ¥è¿è¡ç¸åºçæä½ãå½ç¶æ们ä¹å¯ä»¥çæä¸ä¸ª.gitignoreæ件ï¼éé¢æå®è¦å¿½ç¥çæ件类åï¼ç¶åè¿äºæ件就ä¸ä¼è¢«è·è¸ªï¼ä¸ç®¡æä¹æ¹åä»ä»¬ï¼git statusé½ä¸ä¼æç¤ºä½ éè¦åä»ä¹æä½ã
æ以å½æ们å¨å·¥ä½ç®å½ä¸è¿è¡æ件æä½åï¼è¦å æ·»å å°æååºï¼ç¶ååå°æååºä¸åæ·»å çæä»¶å¿«ç §æ交å°æ¬å°ä»åºï¼ç¶ååå°æ¬å°ä»åºçææ°ç¶ææä»¶å¿«ç §æ¨éå°è¿ç¨ä»åºãè¿ä¸ªæä»¶å¿«ç §å ¶å®å°±æ¯å个æ件å¨è¢«æ·»å å°æååºæ¶çç¶æï¼å°±åç §ç¸çä¸æ ·ï¼çä¸æ¯ä¸ªä¸åæ¶å»çå¿«ç §ï¼æ¹ä¾¿ä»¥åæ¥è¯¢ï¼ègitåå¨çå°±æ¯è¿äºä¸ç³»åçå¿«ç §ã说å°è¿ä¸ªå¿«ç §å°±è¦è¯´è¯´gitç对象äºã
Git对象
å¨.git-ãObjectsæ件夹æ¯ä¸ä¸ªä¸ªçgit对象ï¼æ¯ä½çåå¸å¼ï¼è¿æ ·å°±æå³ç没æ两个ç¸åç对象åã
ä»æ ¹æ¬ä¸è®²ï¼gitæ¯ä¸å¥å 容寻åçæ件系ç»ï¼å®åå¨çä¹æ¯key-valueé®å¼å¯¹ï¼ç¶åæ ¹æ®keyå¼æ¥æ¥æ¾valueçï¼è¯´å°å¯»åå°±ä¼æ³å°æéå§ï¼ä¸éï¼gitä¹æ¯æ ¹æ®æéæ¥å¯»åçï¼è¿äºæéå°±åå¨å¨gitç对象ä¸ãGitä¸å ±æåç§å¯¹è±¡ï¼commit对象ï¼tree对象åblob对象åtag对象ï¼è¿éå¯ä»¥ç解tagæ¯commitçå«åï¼ä¸é¢ä¾¿æ¯è¿ä¸ä¸ªå¯¹è±¡ï¼
æ¯ä¸ªç®å½é½å建äºâtreeâ对象,码链 æ¯ä¸ªæ件é½å建äºä¸ä¸ªå¯¹åºçâblobâ对象ãæåæä¸ä¸ªâcommitâ对象æ¥æåæ ¹âtreeâ对象ï¼è¿æ ·æ们就å¯ä»¥è¿½è¸ªé¡¹ç®æ¯ä¸é¡¹æ交å 容ã
è¿ä¸ªblob对象对åºçå°±æ¯æä»¶å¿«ç §ä¸é£äºåçååçæ件å 容ï¼è
tree对象åè®°å½äºæä»¶å¿«ç §ä¸å个ç®å½åæ件çç»æå ³ç³»ï¼å®æåäºè¢«è·è¸ªçå¿«ç §ï¼
commit对象åè®°å½äºæ¯æ¬¡æ交å°æ¬å°ä»åºçæä»¶å¿«ç §ï¼
ä»å¨å¼åè¿ç¨ä¸ï¼æ们ä¼æ交å¾å¤æ¬¡æä»¶å¿«ç §ï¼é£ä¹ç¬¬ä¸æ¬¡æ交çå 容ä¼ç¨ä¸ä¸ªcommitæ¥è®°å½ï¼è¿ä¸ªcommit 没ææéæåä¸ä¸ä¸ªcommit对象ï¼å 为没æä¸ä¸ä¸ªcommit,ä»æ¯ç¬¬ä¸ä¸ªï¼å½ç¬¬äºæ¬¡æ交æ¶ï¼åä¼æå¦å¤ä¸ä¸ªcommit对象æ¥è®°å½ï¼é£ä¹è¿æ¬¡commit对象ä¸å°±ä¼æä¸ä¸ªæéæåä¸ä¸æ¬¡æ交åçcommit对象ï¼ç»è¿å¾å¤æ¬¡æ交åå°±ä¼æå¾å¤çcommit对象ï¼å®ä»¬ç»æäºä¸ä¸ªé¾è¡¨ï¼å½æ们è¦æ¢å¤åªä¸ªçæ¬çæ¶åï¼åªè¦æ¾å°è¿ä¸ªcommit对象就è½æ¢å¤é£ä¸ªçæ¬çæ件ãèæ们æè°çHEADå¯¹è±¡å ¶å®å°±æ¯æåæè¿ä¸ä¸ªæ交çcommit对象ï¼ä¹å°±æ¯æåä¸ä¸ªcommit对象ã
libevent、libev框架介绍
本文深入讲解了libevent的码链API,并剖析了libevent的码链evbuffer源码。libevent、码链libev和libuv都是码链jewelcad源码C语言实现的异步事件库,主要负责注册异步事件、码链检测异步事件,码链并根据事件的码链触发先后顺序调用相应的回调函数处理事件。这些事件包括网络I/O事件、码链定时事件以及信号事件,码链共同驱动服务器运行。码链
libevent和libev主要封装了与操作系统交互的码链简单事件管理接口,让开发者无需关注平台差异,码链只需处理事件的码链具体逻辑。libev改进了libevent的架构决策,如消除全局变量的使用,采用回调函数传递上下文,构建不同的数据结构以降低事件耦合性,使用最小四叉堆作为计时器,从而实现高效管理。然而,libevent和libev在window平台的支持较差,因此libuv应运而生,基于libev,尤其在window平台上更好地封装了iocp,node.js即基于libuv。炫酷考试源码
在libevent的编译安装过程中,首先从git下载release-2.1.-stable.tar.gz,然后在编译程序时指定库名:-levent。由于头文件和库文件已经复制至系统路径,因此在编译时无需额外指定-I和-L。
libevent的封装层次分为网络封装和解决的问题。网络封装包括IO检测和IO操作,解决的问题涉及连接建立(如最大连接数、黑白名单等)和连接断开,以及数据的到达与发送。如果不想手动操作IO事件,libevent会管理读写I/O处理,使开发者只需处理逻辑,无需关心边界问题。
libevent提供了事件检测与操作的封装。事件检测是低层封装,由libevent负责,用户自定义IO操作。该层次封装了事件管理器操作和事件接口。事件管理器event_base用于构建事件集合,检测事件就绪情况。释放管理器使用event_base_free,event_reinit用于重置,event_get_supported_methods查看支持的方法。
事件循环通过event_base_dispatch和event_base_loop实现,等待事件产生,spring 事务 aop 源码提供类似epoll红黑树循环的功能。事件循环终止使用event_base_loopbreak和event_base_loopexit,前者在事件回调执行后终止,后者立即终止。
事件对象通过event_new创建,event_free销毁。注册与注销事件使用event_add和event_del,事件驱动的核心思想是libevent的核心功能。
libevent事件对象包括只使用事件检测、IO操作自处理的Demo。此外,自带缓冲的事件-bufferevent介绍其作为event的高级版本,拥有两个缓冲区和三个回调函数,分别用于读取、写入和事件处理。
bufferevent提供读写数据到缓冲区的封装,三个回调函数分别处理读取、写入和事件触发。构建、销毁bufferevent对象,以及连接操作、设置回调等。
事件类型注册与注销使用bufferevent_enable/disable,获取读写缓冲区使用bufferevent_get_input和bufferevent_get_output,数据分割使用evbuffer_readln和固定长度读取使用evbuffer_remove。
对于bufferevent,spark源码有多少一个文件描述符对应两个缓冲区和三个回调函数,文件描述符用于与客户端通信,非监听文件描述符。两个缓冲区指读缓冲区和写缓冲区,三个回调分别对应读操作、写操作和事件触发。
链接监听器-evconnlistener封装底层socket通信函数,如socket、bind、listen、accept。创建监听器后,等待新客户端连接,调用用户指定的回调函数。构建监听器使用evconnlistener_new_bind,回调函数evconnlistener_cb接收与客户端通信的描述符和连接对端地址。
信号事件在libevent中与网络事件相似,通过epoll监听。定时事件和网络事件的处理机制基于最小堆与epoll_wait,通过源码分析可深入了解流程。
evbuffer作为libevent底层实现的链式缓冲区,用于bufferevent事件中的数据读写。每个evbuffer由链表组成,包含关键成员和实现细节。evbuffer的优点在于高效处理数据移动和内存浪费,缺点是微软模拟飞行源码数据在不连续内存中存储,可能导致多次io。libev关注具体网络IO事件、定时事件和信号事件,提供API如ev_io_init、ev_io_start、ev_timer_start和ev_run。通过libev宏定义封装,开发者能使用与libevent类似的接口。
Git从入门到精通(下篇)-4-git commit详解
git commit是将暂存区内容提交到代码仓库,形成一个版本的命令。下面,我们详细解读执行git commit后带来的具体变化。
在执行git commit时,会产生两个对象:commit对象和tree对象。
让我们查看commit对象的内容。
同时,观察tree对象的内容。
通过图解,您可以直观地理解这两个对象在git commit过程中的角色。
当进行第二次提交时,我们创建了一个新文件.txt,并提交。
从数据结构的角度,一个commit对象就代表了一个版本。
在第三次提交中,我们修改了test.txt的内容,将其改为hello git~。
进行第四次提交时,我们构建了一个目录,并在目录内创建了一个新文件,操作稍显复杂。
通过git commit,我们可以形成链表+树的结构,实现对象的复用。
综上所述,git commit命令在执行后,不仅实现了代码版本的保存,还通过commit对象和tree对象构建了一种高效的数据结构,便于后续的管理和追踪。
自制处理器系列(一):一生一芯计划-预先学习阶段(P线)
踏入一生一芯的探索,我追随偶像稚晖君的脚步,决心亲手打造自己的处理器。在这个预先学习阶段,我选择了P线的任务,从阅读与理解开始,深入挖掘处理器硬件开发的奥秘。首要任务是撰写两篇文章的读后感,提出有深度的问题,并在实践中独立解决问题。 作为内向的学习者,我深知STFW(Search the documentation, Tech forums, and Work it out yourself)的重要性,曾在大学期间挑战LFS系统编译与ROS机器人的项目,这让我明白自信判断和问题解决能力的不可或缺。面对团队资源有限,我们通过不断努力提升工程实践能力,共同分享ROS开发的经验与技巧。 在处理器的学习之旅中,我计划从基础做起,如安装Linux,编写Hello World程序,理解GCC/GDB/Makefile的运用,这些都是硬件开发的基石。在ROS项目中,获取框架代码时,添加SSH key和修改Makefile细节成为关键步骤。而对于Git管理,遵循PA0讲义,我注重个人信息设置和权限备份,确保代码管理的有序进行。 深入Verilator的世界,我开始阅读官网文档,安装4.版本,掌握基本的git操作,避免盲目追踪源码。通过对比阅读C++和Verilog代码,我理解了仿真过程和波形文件的生成。在编写Makefile时,我专注于实现一键仿真的便捷性,如自动生成的Vswitch.mk文件,它揭示了Verilog到C++模块的转换核心。 在NVBoard项目中,我挑战自建Git跟踪机制,记录每个步骤,以便精确评估。C语言基础任务涉及递归、指针和链表,尽管C语言不那么流行,但它是底层编程的首选工具。掌握高级指针技巧,如以下代码所示:源码链接,是提升编程能力的关键。 接下来的任务涉及Verilator的深入理解,如NVBoard的输入输出配置,以及流水灯模块的开发。理解时序逻辑仿真,如Vled___root___eval中的时钟触发,是提升设计能力的重要一环。 为了深化实践,我推荐使用南京大学的《数字电路与计算机组成实验》,在实验中磨炼数字电路设计和调试技能。通过NEMU,我们学习调试技巧,实现表达式求值,这不仅是编程实践,也是对编译原理的深入理解。 面对PA1的挑战,我明白编译原理的复杂性,如词法分析和语法解析。正则表达式在Token识别中的运用,以及处理运算符优先级,成为我攻克的难点。但每一次的突破,都让我更加坚定地提升自我,向一生一芯的目标稳步前行。wait(linux kernel 等待队列)
Linux内核中的等待队列是同步和异步事件处理的常见工具。它在资源访问控制和事件通知中扮演着关键角色。想象一下,任务A想要对某个模块执行操作,但条件尚未成熟,这时任务A会通过等待队列进入休眠状态,直到条件满足。这时,模块会将A从队列中唤醒。 与信号量相比,等待队列提供了更多灵活性。虽然两者原理相似,涉及节点的申请和挂载,以及进程的挂起与唤醒,但等待队列允许自定义唤醒条件,可一次性唤醒多个进程,让它们各自检查条件是否满足。核心结构包括wait_queue_head作为链表头部,wait_queue_entry记录进程指针,等待队列头需要用户手动定义,而wait_queue_entry则在API中隐含处理。 快速使用等待队列的步骤包括:包含相关头文件,初始化等待队列头,资源访问者通过wait_event等待条件,提供者通过wake_up唤醒。例如:初始化:#include "wait.h",init_waitqueue_head(wq_head)
等待:wait_event(wq_head, condition),等待条件成立
唤醒:wake_up(wq_head)
在源码中,可以参考kernel/sched/wait.c和include/linux/wait.h。了解更多细节,可以通过查阅5..5版本的git.kernel.org链接。下面是一些关键函数的源码剖析:初始化等待队列头:主要设置锁和链表
wait_event的底层实现:涉及宏展开和唤醒回调函数
wake_up函数:执行唤醒任务,通常调用try_to_wake_up,涉及唤醒回调和通用唤醒任务处理
深入理解等待队列的运作,有助于我们更好地控制和管理内核中的并发行为。欲了解更多Linux内核源码解析,请关注我的专栏:RTFSC(Linux kernel源码轻松读)。