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


对于广大C语言开发者来说,缺乏类似C++ STL和Boost的库会让开发受制于基础库的匮乏,也因此导致了开发效率的骤降。这也使得例如libevent这类事件库(基础组件库)一时间大红大紫。

今天,码哥给大家带来一款基础库,这套库不仅仅提供了常用的数据结构、算法,如红黑树、斐波那契堆、队列、KMP算法、RSA算法、各类哈希算法、数据恢复算法等等,还提供了多进程框架、多线程框架、跨平台高性能事件等实用内容。注意:这是一款不依赖第三方的库。

除此以外,它也是笔者之前文章(Melang脚本语言)中的核心库。这也就意味着,使用该库,不仅可以快速获得上述内容,还可以让开发者所构建的系统很方便地引入脚本语言的功能。

它就是——Melon
在这里插入图片描述

GitHub - Water-Melon/Melon: A generic cross-platform C library, including a lot of components, frameworks and a new coroutine script language Melang.

下面,码哥便带诸位一览这个库的功能。

数据结构

Melon中包含如下数据结构的实现:

  • 双向链表
  • 斐波那契堆
  • 哈希表
  • 队列
  • 红黑树
  • 数组

其中:

  • 双向链表使用宏实现,可以通过两行宏函数即可完成双向队列插入和删除操作的声明和定义。
  • 斐波那契堆是一个最小堆,在库中的事件功能中用于实现定时器的维护管理,当然,也可以单独使用。

以上结构几乎均可在其对应名称的头文件中找到数据结构定义以及函数定义。

一般情况下,数据结构的使用都是函数调用形式,因此也尽可能降低了不同组件间的耦合度。

算法

Melon中包含的算法如下:

  • 加密算法:AES、DES、3DES、RC4、RSA
  • 哈希算法:MD5、SHA1、SHA256
  • Base64
  • 大数计算
  • FEC
  • JSON
  • 矩阵运算
  • 里德所罗门编码
  • 正则匹配算法
  • KMP

如上算法基本都在其各自头文件中可以找到对应的函数声明以及必要的数据结构定义。

其中,FEC与里德所罗门编码均属于纠错码,FEC常用于RTP中做数据修复,而里德所罗门编码既可以用于实时语音中丢包恢复,也可以用于冗余阵列(RAID)和其他UDP丢包恢复的场景。关于里德所罗门编码,感兴趣的读者可以阅读码哥之前的文章:神奇的数据恢复算法。

其他组件

前面的都是常规操作,这里才是重头戏。

Melon中还包括如下实用组件:

  • 内存池
  • 数据链
  • TCP封装
  • 事件机制
  • 文件缓存
  • HTTP处理
  • 脚本语言
  • 词法分析器
  • websocket
  • 多进程框架
  • 多线程框架

因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_framework.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_framework_attr attr;attr.argc = argc;attr.argv = argv;attr.global_init = global_init;attr.master_process = NULL;attr.worker_process = worker_process;return mln_framework_init(&attr);
}static int global_init(void)
{//global variable init functionint n = snprintf(text, sizeof(text)-1, "hello world\n");text[n] = 0;return 0;
}static void worker_process(mln_event_t *ev)
{//we can set event handler here//let's set a timermln_event_timer_set(ev, 1000, text, print_handler);
}static void print_handler(mln_event_t *ev, void *data)
{mln_log(debug, "%s\n", (char *)data);mln_event_timer_set(ev, 1000, data, print_handler);
}

这段代码主要是初始化了一个全局变量,然后给每一个子进程创建了一个定时事件,即每一秒中输出一个hello world。

我们先进行编译链接生成可执行程序:

$ cc -o hello hello.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon

然后,我们需要先修改Melon库的配置文件:

$ sudo vim /usr/local/melon/conf/melon.conflog_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";
}

我们做如下修改:

framework off; --> framework "multiprocess";
worker_proc 1; --> worker_proc 3;

这样,多进程框架将被启用,且会产生三个子进程。

程序启动后如下:

$ ./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 world02/08/2021 09:34:46 GMT DEBUG: hello.c:print_handler:39: PID:25323 hello world02/08/2021 09:34:46 GMT DEBUG: hello.c:print_handler:39: PID:25324 hello world02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25322 hello world02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25323 hello world02/08/2021 09:34:47 GMT DEBUG: hello.c:print_handler:39: PID:25324 hello world...

这时,可以ps看一下,一共存在四个hello进程,一个为主,其余三个为子进程。

小结

事实上,Melon并不会有过多条条框框需要开发者小心谨慎怕踩坑。与Skynet类似,Melon提供的绝大多数内容都可独立使用,而不必一定与多进程多线程框架结合。因此,这也给了使用者极大的自由度。

Melon的官方QQ群号:756582294

感谢阅读,欢迎各位在评论区留言评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Privoxy 实现对多域名的定向转发

需求与思路 内网一台主机想要访问公网的两个不同站点, 想要实现访问两个站点时表现出不同的公网 IP 地址. 即在公网的站点服务器端看到的客户端 IP 是不同的. 思路是搭建两台具有不同公网 IP 的服务器, 分别安装配置 Privoxy 后进行串联, 并将其中一台作为主服务器暴露给内网…

操作系统期末复习资料

操作系统引论 计算机操作系统的功能是 。 A. 把源程序代码转换为目标代码 B. 实现计算机用户之间的相互交流 C. 完成计算机硬件与软件之间的转换 D. 控制、管理计算机系统的资源和程序的执行 010110011020100 D 010110021020101 操作系统是一组 。…

JavaScript进阶(事件+获取元素+操作元素)

目录 事件基础 事件组成 执行事件的步骤 获取元素 根据ID获取元素 根据标签名获取元素 获取ol中的小li 类选择器&#xff08;html5新增的I9以上支持&#xff09; 获取body和html 操作元素 innerText和innerHtml 表单标签 样式属性操作 操作元素总结 事件基础 事…

yolov5知识蒸馏

参考代码&#xff1a;https://github.com/Adlik/yolov5 https://cloud.tencent.com/developer/article/2160509 yolov5间的模型蒸馏&#xff0c;相同结构的。 配置参数 parser.add_argument(--t_weights, typestr, default./weights/yolov5s.pt,helpinitial teacher model wei…

JY901S 9轴姿态角度传感器模块

JY901S 9轴姿态角度传感器模块 JY901S 简介模块特性引脚说明IIC通讯IIC读写寄存器代码示例 JY901S 简介 模块集成高精度的陀螺仪、加速度计、地磁场传感器&#xff0c;采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法&#xff0c;能够快速求解出模块当前的实时运…

xtu oj 1055 整数分类

Description 按照下面方法对整数x进行分类&#xff1a;如果x是一个个位数&#xff0c;则x属于x类&#xff1b;否则将x的各位上的数码累加&#xff0c;得到一个新的x&#xff0c;依次迭代&#xff0c;可以得到x的所属类。比如说24&#xff0c;246&#xff0c;则24的类别数是6&a…

基于Python的新能源汽车销量分析与预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 基于Python的新能源汽车销量分析与预测系统是一个使用Python编程语言和Flask框架开发的系统。它可以帮助用户分析和预测新能源汽车的销量情况。该系统使用了关系数据库进行数据存储&#xff0c;并…

相机标定资料大全

目录 yolov5 双目测距: 标定,双目测距 https://github.com/suqinglee/binocular-vision-measurement

MATLAB信号处理与应用 读书笔记 一

完成了基本操作&#xff0c;今天组数也正常&#xff0c;需要对应解决fsctrl文件中的信号处理相关 重点关注4傅里叶变换&#xff0c;6FIR滤波器&#xff0c;10信号处理中的应用字符的链接[aa,bb]&#xff1b; N18;N216; n0:N-1;k10:N1-1;k20:N2-1; w2*pi*(0:2047)/2048; Xw(1-…

【并发设计模式】聊聊 基于Copy-on-Write模式下的CopyOnWriteArrayList

在并发编程领域&#xff0c;其实除了使用上一篇中的属性不可变。还有一种方式那就是针对读多写少的场景下。我们可以读不加锁&#xff0c;只针对于写操作进行加锁。本质上就是读写复制。读的直接读取&#xff0c;写的使用写一份数据的拷贝数据&#xff0c;然后进行写入。在将新…

CSS5 | CSS滑动门左扇与右扇图片重叠问题解决

本文中所使用的滑动门背景图片是自己用微软相册手工切的&#xff0c;没用ps&#xff0c;所以凑乎看吧 首先放出一张目标效果也是最终完成图 下面说问题 CSS推拉门原理 按原理来说&#xff0c;就是两个行内块前后站一行&#xff0c;然后前面的a标签和span标签分别是推拉门素材…

添加与搜索单词 - 数据结构设计[中等]

一、题目 请你设计一个数据结构&#xff0c;支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。 实现词典类WordDictionary&#xff1a; 1、ordDictionary()初始化词典对象 2、void addWord(word)将word添加到数据结构中&#xff0c;之后可以对它进行匹配 3、b…

对递归、循环和迭代的理解

递归、循环和迭代都是编程和算法中非常重要的知识&#xff0c;以下是本人对他们的理解&#xff0c;若有不对&#xff0c;还希望大家可以批评指正&#xff01; 递归&#xff1a;将一个大问题分解成多个相似的小问题&#xff0c;再将小问题分成更小的相似问题&#xff0c;然后逐个…

解密 Java ForEach 提前终止问题

目录 前言&#xff1a;场景复现分析与解决方案解决方案详解总结 前言&#xff1a; 你是否曾在使用 Java 8 的 forEach 迭代集合时遇到过提前终止循环的问题&#xff1f;在这篇博客中&#xff0c;我们将深入探讨这一问题&#xff0c;并提供多种解决方案。通过场景复现、分析源码…

Arduino驱动TMF8701 ToF激光测距传感器(距离传感器)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 <

TCP 三次握手:四次挥手

TCP 三次握手/四次挥手 TCP 在传输之前会进行三次沟通&#xff0c;一般称为“三次握手”&#xff0c;传完数据断开的时候要进行四次沟通&#xff0c;一般称为“四次挥手”。 数据包说明 源端口号&#xff08; 16 位&#xff09;&#xff1a;它&#xff08;连同源主机 IP 地址…

生成二维码,条形码,带数字,输出到文件

生成二维码和条形码 依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.google.zxing</groupId><a…

验证码服务使用指南

验证码服务使用指南 1 部署验证码服务 1.1 基础环境 Java 1.8 Maven3.3.9 1.2 安装Redis 参考“Redis安装指南” 1.3 部署验证码服务 1.3.1 下载源码 使用git从远程下载验证码服务代码(开源)。 1.3.2 使用idea打开项目 使用idea打开上一步下载的sailing目录&#xf…

优维产品最佳实践第20期:控制台全链路监控

之前我们会觉得cmdb自动发现没有上报很难排查&#xff0c;弄不清楚数据的上报链路&#xff1b;监控指标的数据断点很难定位&#xff0c;flink对现场来说是一个黑盒子&#xff1b;apm数据更新不及时到底是上报异常还是入库失败呢&#xff1f; 现在控制台集成了对数据链路的监控…

超声系统前端理论与模拟仿真-续

作者&#xff1a;蒋志强 本人同意他人对我的文章引用&#xff0c;但请在引用时注明出处&#xff0c;谢谢&#xff0e;作者&#xff1a;蒋志强 前言 近期整理了一下彩超前端及波束合成相关的内容&#xff0c;很早以前已经有过一次&#xff0c;这次把其它的内容总结一下&#xf…