本文转载自本人头条号: https://www.toutiao.com/i6926789516594479624/
转载请注明出处,感谢!
对于广大C语言开发者来讲,缺少相似C++ STL和Boost的库会让开发受制于基础库的匮乏,也所以致使了开发效率的骤降。这也使得例如libevent这类事件库(基础组件库)一时间大红大紫。git
今天,码哥给你们带来一款基础库,这套库不只仅提供了经常使用的数据结构、算法,如红黑树、斐波那契堆、队列、KMP算法、RSA算法、各种哈希算法、数据恢复算法等等,还提供了多进程框架、多线程框架、跨平台高性能事件等实用内容。注意:这是一款不依赖第三方的库。github
除此之外,它也是笔者以前文章(Melang脚本语言)中的核心库。这也就意味着,使用该库,不只能够快速得到上述内容,还可让开发者所构建的系统很方便地引入脚本语言的功能。web
它就是——Melon算法
Github:https://github.com/Water-Melon/Melon。vim
下面,码哥便带诸位一览这个库的功能。缓存
Melon中包含以下数据结构的实现:bash
其中:websocket
以上结构几乎都可在其对应名称的头文件中找到数据结构定义以及函数定义。数据结构
通常状况下,数据结构的使用都是函数调用形式,所以也尽量下降了不一样组件间的耦合度。多线程
Melon中包含的算法以下:
如上算法基本都在其各自头文件中能够找到对应的函数声明以及必要的数据结构定义。
其中,FEC与里德所罗门编码均属于纠错码,FEC经常使用于RTP中作数据修复,而里德所罗门编码既能够用于实时语音中丢包恢复,也能够用于冗余阵列(RAID)和其余UDP丢包恢复的场景。关于里德所罗门编码,感兴趣的读者能够阅读码哥以前的文章:神奇的数据恢复算法。
前面的都是常规操做,这里才是重头戏。
Melon中还包括以下实用组件:
因Melon做者Nginx中毒较深,因此Melon中部分机制与Nginx较为类似。
内存池:这里内存池不只支持对从堆中分配的内存进行管理,还支持对共享内存的管理。
数据链与TCP封装:TCP封装中包含了阻塞与非阻塞下的收发逻辑,并利用数据链结构来存放发送数据与接收数据。
事件机制:事件机制中不只支持epoll、select,还支持Kqueue,库在编译前会自行检测平台支持状况。事件包含了:
文件缓存:参考Nginx文件缓存,避免对同一文件的重复打开浪费文件描述符资源。
HTTP:包含了HTTP的接收解析和发送,该套接口依赖于数据链结构来进行处理,所以可配合TCP封装一同使用。
脚本语言:内容较多,可另行参考:Melang脚本语言。
词法分析器:之因此这个单独算一个功能组件,是由于在Melon中,配置文件解析就是使用该词法分析器处理的。仅经过三行C代码就能够实现一个最最基础的词法分析器,这也归功于C语言宏的强大。
websocket:该部分依赖于HTTP组件。
多进程:多进程采用一主多从模式,主进程作管理,从进程处理实际业务。主进程与从进程之间由socketpair相连,所以从进程异常退出,主进程会马上拉起一个新的子进程,同时主子进程也能够经过该socketpair进行数据通讯。除了自身子进程能够管理,也能够经过配置文件配置来拉起其余程序做为本身的子进程来管理,有些相似于supervisord。
多线程:多线程分为两类,一类是常规的线程池,另外一类是模块化的线程。后者也是一主多从模型,主与子之间是经过socketpair进行通讯,而每个子线程都有其入口函数(相似main函数),每个子线程一般都是处理一类单一事务。
上面说了那么多,下面就来看一个多进程的例子。
首先,咱们要先安装Melon:
$ git clone https://github.com/Water-Melon/Melon.git $ ./configure $ make $ sudo make install $ sudo echo "/usr/local/melon/lib/" >> /etc/ld.so.conf $ sudo ldconfig
安装好后,Melon会被安装在/usr/local/melon下。
接着,咱们建立一个名为hello.c的源文件来完成咱们指望的功能:
#include <stdio.h> #include "mln_core.h" #include "mln_log.h" #include "mln_event.h" char text[1024]; static int global_init(void); static void worker_process(mln_event_t *ev); static void print_handler(mln_event_t *ev, void *data); int main(int argc, char *argv[]) { struct mln_core_attr cattr; cattr.argc = argc; cattr.argv = argv; cattr.global_init = global_init; cattr.worker_process = worker_process; return mln_core_init(&cattr); } static int global_init(void) { //global variable init function int n = snprintf(text, sizeof(text)-1, "hello worldn"); text[n] = 0; return 0; } static void worker_process(mln_event_t *ev) { //we can set event handler here //let's set a timer mln_event_set_timer(ev, 1000, text, print_handler); } static void print_handler(mln_event_t *ev, void *data) { mln_log(debug, "%sn", (char *)data); mln_event_set_timer(ev, 1000, data, print_handler); }
这段代码主要是初始化了一个全局变量,而后给每个子进程建立了一个定时事件,即每一秒中输出一个hello world。
咱们先进行编译连接生成可执行程序:
$ gcc -o hello hello.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon
而后,咱们须要先修改Melon库的配置文件:
$ sudo vim /usr/local/melon/conf/melon.conf log_level "none"; //user "root"; daemon off; core_file_size "unlimited"; //max_nofile 1024; worker_proc 1; thread_mode off; framework off; log_path "/usr/local/melon/logs/melon.log"; /* * Configurations in the 'exec_proc' are the * processes which are customized by user. * * Here is an example to show you how to * spawn a program. * keepalive "/tmp/a.out" ["arg1" "arg2" ...] * The command in this example is 'keepalive' that * indicate master process to supervise this * process. If process is killed, master process * would restart this program. * If you don't want master to restart it, you can * default "/tmp/a.out" ["arg1" "arg2" ...] * * But you should know that there is another * arugment after the last argument you write here. * That is the file descriptor which is used to * communicate with master process. */ exec_proc { // keepalive "/tmp/a"; } thread_exec { // restart "hello" "hello" "world"; // default "haha"; }
咱们作以下修改:
这样,多进程框架将被启用,且会产生三个子进程。
程序启动后以下:
$ ./hello Start up worker process No.1 Start up worker process No.2 Start up worker process No.3 02/08/2021 09:34:46 GMT DEBUG: hello.c:print_handler:39: PID:25322 hello world 02/08/2021 09:34:46 GMT DEBUG: hello.c:print_handler:39: PID:25323 hello world 02/08/2021 09:34:46 GMT DEBUG: hello.c:print_handler:39: PID:25324 hello world 02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25322 hello world 02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25323 hello world 02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25324 hello world ...
这时,能够ps看一下,一共存在四个hello进程,一个为主,其他三个为子进程。
事实上,Melon并不会有过多条条框框须要开发者当心谨慎怕踩坑。与Skynet相似,Melon提供的绝大多数内容均可独立使用,而没必要必定与多进程多线程框架结合。所以,这也给了使用者极大的自由度。
Melon的官方QQ群号:756582294
感谢阅读,欢迎各位在评论区留言评论。