当前位置: 首页 > Linux

开发利器-C语言必备实用第三方库

时间:2023-04-06 01:40:46 Linux

本文转载自本人头条号:https://www.toutiao.com/i6926789516594479624/转载请注明出处,谢谢!对于广大的C语言开发者来说,缺少类似于C++STL和Boost的类库会让开发受制于基础库的缺乏,这也会导致开发效率骤降。这也使得像libevent这样的事件库(基础组件库)一时间非常流行。今天麻哥给大家带来一个基础库。这个库不仅提供了常用的数据结构和算法,如红黑树、斐波那契堆、队列、KMP算法、RSA算法以及各种哈希。算法、数据恢复算法等,还提供了多进程框架、多线程框架、跨平台高性能事件等实用内容。注:这是一个不依赖第三方的库。另外,它也是笔者上一篇文章(Melang脚本语言)中的核心库。这也意味着使用这个库不仅可以快速获取以上内容,还可以让开发者很方便的将脚本语言的功能引入到自己搭建的系统中。它是-MelonGithub:https://github.com/Water-Melon/Melon。下面码哥就给大家介绍一下这个库的功能。数据结构Melon包括了以下数据结构的实现:双向链表、斐波那契堆、哈希表、队列、红黑树栈,其中:双向链表是用宏实现的,两行宏函数可以用于完成双向队列插入删除操作的声明和定义。斐波那契堆是一个最小堆,用在库的事件函数中,实现定时器的维护和管理。当然,它也可以单独使用。几乎所有的上述结构都可以在其对应名称的头文件中找到数据结构定义和函数定义。一般来说,数据结构的使用都是以函数调用的形式进行的,所以也尽可能的降低了不同组件之间的耦合度。算法Melon中包含的算法如下:加密算法:AES、DES、3DES、RC4、RSAHash算法:MD5、SHA1、SHA256Base64大数计算FECJSON矩阵运算Reed-Solomon编码正则匹配算法KMP以上算法基本都在它们各自对应的函数声明和必要的数据结构定义都可以在头文件中找到。其中,FEC和Reed-Solomon编码都是纠错码。FEC常用于RTP中的数据修复,而Reed-Solomon编码可用于实时语音中的丢包恢复,也可用于冗余阵列(RAID)等UDP丢包恢复场景。关于Reed-Solomon编码,感兴趣的读者可以阅读码哥的上一篇文章:神奇的数据恢复算法。其他组件都是常规操作,这里是重头戏。Melon还包括以下实用组件:内存池数据链接TCP封装事件机制文件缓存HTTP处理脚本语言词法分析器websocket多进程框架多线程框架由于Melon作者深受Nginx毒害,Melon中的一些机制类似到Nginx。内存池:这里的内存池不仅支持管理从堆中分配的内存,还支持管理共享内存。数据链路和TCP封装:TCP封装包括阻塞和非阻塞下的发送和接收逻辑,使用数据链路结构存储发送数据和接收数据。事件机制:事件机制不仅支持epoll和select,还支持Kqueue。库会在编译前自行检测平台支持。事件包括:handle(文件描述符)事件:read、write、error事件、timeout事件(主要用于超时断开);计时事件(不同于句柄超时);signalprocessingevents:这里的信号处理并不是说一个信号只能有一个处理事件,而是设置多少个处理函数都会执行;文件缓存:参考Nginx文件缓存,避免重复打开同一个文件浪费文件描述符资源。HTTP:包括HTTP的接收、解析和发送。该套接字依赖于数据链路结构进行处理,因此可以与TCP封装一起使用。脚本语言:内容较多,可参考:Melang脚本语言。词法分析器:之所以把它算作一个功能组件,是因为在Melon中,配置文件的解析就是用这个词法分析器来处理的。最基本的词法分析器只需要三行C代码就可以实现,这也是得益于C语言宏的强大功能。websocket:这部分依赖于HTTP组件。多进程:多进程采用主多从模式,主进程管理,从进程处理实际业务。master进程和slave进程是通过socketpair连接的,所以当slave进程异常退出时,master进程会立即拉起一个新的子进程,主子进程也可以通过socketpair进行数据通信。它除了管理自己的子进程外,还可以通过配置文件配置拉起其他程序作为自己的子进程进行管理,有点类似于supervisord。多线程:多线程分为两大类,一类是常规线程池,一类是模块化线程。后者也是一主多从模型。master和child通过socketpair进行通信,每个子线程都有自己的入口函数(类似于main函数),每个子线程通常处理单一类型的事务。上面说了这么多,我们来看一个多进程的例子。首先,我们需要安装Melon:$gitclonehttps://github.com/Water-Melon/Melon.git$./configure$make$sudomakeinstall$sudoecho"/usr/local/melon/lib/">>/etc/ld.so.conf$sudoldconfig安装完成后,Melon会安装在/usr/local/melon下。接下来,我们创建一个名为hello.c的源文件来完成我们想要的功能:#include#include"mln_core.h"#include"mln_log.h"#include"mln_event.h"chartext[1024];静态intglobal_init(无效);staticvoidworker_process(mln_event_t*ev);staticvoidprint_handler(mln_event_t*ev,void*data);intmain(intargc,char*argv[]){structmln_core_attrcattr;cattr.argc=argc;cattr.argv=argv;cattr.global_init=global_init;cattr.worker_process=worker_process;returnmln_core_init(&cattr);}staticintglobal_init(void){//全局变量初始化函数intn=snprintf(text,sizeof(text)-1,"helloworldn");文本[n]=0;return0;}staticvoidworker_process(mln_event_t*ev){//我们可以在这里设置事件处理程序//让我们设置一个定时器mln_event_set_timer(ev,1000,text,print_handler);}staticvoidprint_handler(mln_event_t*ev,void*data){mln_log(调试,"%sn",(char*)data);mln_event_set_timer(ev,1000,数据,print_handler);这段代码主要初始化一个全局变量,然后为每个子进程创建一个计时事件,即每秒输出一个helloworld我们先进行编译链接生成可执行程序:$gcc-ohellohello.c-I/usr/local/melon/include/-L/usr/local/melon/lib/-lmelon然后,我们需要先修改Melon库的配置文件:$sudovim/usr/local/melon/conf/melon.conflog_level"none";//user"root";daemonoff;core_file_size"unlimited";//max_nofile1024;worker_proc1;thread_modeoff;frameworkoff;log_path"/usr/local/melon/logs/melon.log";/**'exec_proc'中的配置是*用户自定义的进程。**下面是一个示例,向您展示如何*生成一个程序。*keepalive"/tmp/a.out"["arg1""arg2"...]*这个例子中的命令是'keepalive'*指示主进程监督这个*进程。如果进程被终止,主进程*将重新启动该程序。*如果你不想让master重启它,你可以*default"/tmp/a.out"["arg1""arg2"...]**但你应该知道在最后一个参数之后还有另一个参数你在这里写的论点。*这是用于*commun的文件描述符与主进程结合。*/exec_proc{//keepalive"/tmp/a";}thread_exec{//restart"hello""hello""world";//default"haha";}我们做了以下更改:frameworkoff;-->框架上;worker_proc1;-->worker_proc3;这样会启用多进程框架,程序启动后会生成三个子进程:$./helloStartupworkerprocessNo.1StartupworkerprocessNo.2Startup工作进程No.302/08/202109:34:46GMTDEBUG:hello.c:print_handler:39:PID:25322helloworld02/08/202109:34:46GMTDEBUG:hello.c:print_handler:39:PID:25323helloworld02/08/202109:34:46GMT调试:hello.c:print_handler:39:PID:25324helloworld02/08/202109:34:47GMT调试:hello.c:print_handler:39:PID:25322helloworld02/08/202109:34:47GMT调试:hello.c:print_handler:39:PID:25323helloworld02/08/202109:34:47GMT调试:hello.c:print_handler:39:PID:25324helloworld...这时候可以ps看到一共有四个hello进程,一个是主进程,另外三个是子进程。总结事实上,Melon并没有太多规章制度要求开发者谨慎行事,不要踩坑。与Skynet类似,Melon提供的大部分内容都可以独立使用,不必与多进程多线程框架结合使用。因此,这也给了用户很大的自由度。瓜子官方QQ群号:756582294感谢阅读,欢迎大家在评论区留言。