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

news2024/9/23 5:25:35


对于广大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 function
    int 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 timer
    mln_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.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";
}

我们做如下修改:

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 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

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

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

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

相关文章

Mybatis如何兼容各类日志?

文章目录 适配器模式日志模块代理模式1、静态代理模式2、JDK动态代理 JDBC Logger总结 Apache Commons Logging、Log4j、Log4j2、java.util.logging 等是 Java 开发中常用的几款日志框架&#xff0c;这些日志框架来源于不同的开源组织&#xff0c;给用户暴露的接口也有很多不同…

Ascon加解密算法分析

参数定义 加密架构图 整个过程是在处理320bits的数据&#xff0c;所以在最开始需要对原始的数据进行一个初始化&#xff0c;获得320bits的数据块&#xff0c; 图里看到的pa和pb都是在做置换&#xff08;对320bits的数据进行一个置换&#xff09; 置换&#xff08;Permutation&…

04|提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案

04&#xff5c;提示工程&#xff08;上&#xff09;&#xff1a;用少样本FewShotTemplate和ExampleSelector创建应景文案 当你用 print 语句打印出最终传递给大模型的提示时&#xff0c;一切就变得非常明了。 您是一位专业的鲜花店文案撰写员。 对于售价为 50 元的 玫瑰 &…

c++使用强制转换类型

对于c中的强制转换&#xff0c;这里主要是讲解的是父类与子类之间的类型强制转换。对于以下的代码中&#xff0c;主要是父类Monkey和子类Man之间的成员函数的调用。 // 这是父类 class Monkey { public&#xff1a; // 定义一个纯虚函数 virtual void printFunc() { qDeb…

udp多播/组播那些事

多播与组播 多播&#xff08;multicast&#xff09;和组播&#xff08;groupcast&#xff09;是相同的概念&#xff0c;用于描述在网络中一对多的通信方式。在网络通信中&#xff0c;单播&#xff08;unicast&#xff09;是一对一的通信方式&#xff0c;广播&#xff08;broad…

智能优化算法应用:基于食肉植物算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于食肉植物算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于食肉植物算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.食肉植物算法4.实验参数设定5.算法结果6.…

算法学习系列(十一):KMP算法

目录 引言一、算法概念二、题目描述三、思路讲解三、代码实现四、测试 引言 这个KMP算法就是怎么说呢&#xff0c;就是不管算法竞赛还是找工作笔试面试&#xff0c;都是非常爱问爱考的&#xff0c;其实也是因为这个算法比较难懂&#xff0c;其实就是很难&#xff0c;所以非常个…

不同参数规模大语言模型在不同微调方法下所需要的显存总结

原文来自DataLearnerAI官方网站&#xff1a; 不同参数规模大语言模型在不同微调方法下所需要的显存总结 | 数据学习者官方网站(Datalearner)https://www.datalearner.com/blog/1051703254378255 大模型的微调是当前很多人都在做的事情。微调可以让大语言模型适应特定领域的任…

Vue在页面上添加水印

第一步&#xff1a;在自己的项目里创建一个js文件&#xff1b;如图所示我在在watermark文件中创建了一个名为waterMark.js文件。 waterMark.js /** 水印添加方法 */ let setWatermark (str1, str2) > {let id 1.23452384164.123412415if (document.getElementById(id) …

数据库01_增删改查

1、什么是数据&#xff1f;什么是数据库&#xff1f; 数据&#xff1a;描述事物的符号记录称为数据。数据是数据库中存储的基本对象。数据库&#xff1a;存放数据的仓库&#xff0c;数据库中可以保存文本型数据、二进制数据、多媒体数据等数据 2、数据库的发展 第一阶段&…

H266/VVC帧内预测编码技术概述

预测编码技术 预测编码&#xff08;Prediction Coding&#xff09;是指利用已编码的一个或多个样本值&#xff0c;根据某种模型或方法&#xff0c;对当前的样本值进行预测&#xff0c;并对样本真实值和预测值之间的差值进行编码。 视频中的每个像素看成一个信源符号&#xff…

MFC读取文件数据,添加信息到列表并保存到文件

打开并读取文件信息 添加&#xff1a; BOOL infoDlg::OnInitDialog() {CDialogEx::OnInitDialog();// TODO: 在此添加额外的初始化AfxMessageBox("欢迎查看学生信息");SetList();return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属…

Node 源项目定制化、打包并使用全过程讲解

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是全栈工…

分布式面试题-理论部分(十二道)

文章目录 分布式面试题&#xff08;十二道&#xff09;分布式理论1. 说说CAP原理2. 为什么CAP不可兼得呢&#xff1f;3. CAP对应的模型和应用&#xff1f;4. BASE理论了解吗&#xff1f; 分布式锁5. 有哪些分布式锁的实现方案呢&#xff1f;**5.1 MySQL分布式锁如何实现呢&…

[2023-年度总结]凡是过往,皆为序章

原创/朱季谦 2023年12月初&#xff0c;傍晚&#xff0c;在深圳的小南山看了一场落日。 那晚我们坐在山顶的草地上&#xff0c;拍下了这张照片——仿佛在秋天的枝头上&#xff0c;结出一颗红透的夕阳。 这一天很快就会随着夜幕的降临&#xff0c;化作记忆的碎片&#xff0c;然…

PoE交换机传输距离是多少?100米?250米?

你们好&#xff0c;我的网工朋友。 今天和你聊聊PoE交换机&#xff0c;之前有系统地给你讲解过一篇&#xff0c;可以先回顾一下哈&#xff1a;《啥样的交换机才叫高级交换机&#xff1f;这张图告诉你》 为什么都说PoE交换机好&#xff1f;它最显著的特点就是&#xff1a; 可…

openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM

文章目录 openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM openGauss学习笔记-173 openGauss 数据库运维-备份与恢复-导入数据-对表执行VACUUM 如果导入过程中&#xff0c;进行了大量的更新或删除行时&#xff0c;应运行VACUUM FULL命令&…

【2024 行人重识别最新进展】ReID3D:首个关注激光雷达行人 ReID 的工作!

【2024 行人重识别最新进展】ReID3D&#xff1a;首个关注激光雷达行人 ReID 的工作&#xff01; 摘要&#xff1a;数据集&#xff1a;方法模型&#xff1a;多任务预训练&#xff1a;ReID Network&#xff1a; 实验结果&#xff1a;结论&#xff1a; 来源&#xff1a;Arxiv 2023…

Jenkins的特殊操作定时自动执行任务以及测试报告调优

java -Dhudson.model.DirectoryBrowserSupport.CSP -jar Jenkins.war 测试报告 不美丽 执行上面的代码 重启jenkins 就好了

Ensp dhcp全局地址池(配置命令 + 实例)

使用DHCP的好处&#xff1a;减少管理员的工作量、避免输入错误的可能、避免ip冲突 DHCP报文类型&#xff1a; DHCP DISCOVER:客户端用来寻找DHCP服务器 DHCP OFFER:DHCP服务器用来响应DHCP DISCOVER报文&#xff0c;此报文携带了各种配置信息 DHCP REQUEST:客户端配置请求确…