开发利器——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 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.mfbz.cn/a/437576.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【开源物联网平台】FastBee认证方式和MQTT主题设计

&#x1f308; 个人主页&#xff1a;帐篷Li &#x1f525; 系列专栏&#xff1a;FastBee物联网开源项目 &#x1f4aa;&#x1f3fb; 专注于简单&#xff0c;易用&#xff0c;可拓展&#xff0c;低成本商业化的AIOT物联网解决方案 目录 一、接入步骤 1.1 设备认证 1.2 设备交…

思维题(蓝桥杯 填空题 C++)

目录 题目一&#xff1a; ​编辑 代码&#xff1a; 题目二&#xff1a; 代码&#xff1a; 题目三&#xff1a; 代码&#xff1a; 题目四&#xff1a; 代码&#xff1a; 题目五&#xff1a; 代码&#xff1a; 题目六&#xff1a; 代码七&#xff1a; 题目八&#x…

Unity Samples和帧动画的问题

拖动序列帧图片和自己创建clip的帧率不同 我今天在创建帧动画的时候用了两种方式第一种是直接拖动序列帧图片到Hierachy&#xff0c;然后生成的第二种是这样我发现两者播放的动画速率不一样最后查了半天查不到原因。最后发现是Samples的原因&#xff0c;而且Unity把Samples这个…

自动化测试框架、Python面向对象以及POM设计模型简介

1 自动化测试框架概述 所谓的框架其实就是一个解决问题的思维&#xff0c;前言中描述的诸多问题如果得到解决&#xff0c;自然而然这种得到良好解决的东西它就可以称之为一个框架&#xff0c;只是这个框架用来解决如何组织开展自动化测试。一个典型的自动化测试框架一般包括测…

市场复盘总结 20240307

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 89% 最常用的…

[OpenCv]频域处理

目录 前言 一、频域变换 1.傅里叶变换 2.代码实现 二、频域中图像处理 1.理解数字图片的频谱 2.频域图像处理步骤 3.使用低通滤波器实现图像平滑 4.使用高通滤波器实现图像锐化 三、总结 前言 数字图像处理的方法有两大类&#xff1a;一种是空间域处理法&#xff0c;…

【笔记】Android Telephony 漫游SPN显示定制(Roaming Alpha Tag)

一、功能名词简介和显示规则 Alpha Tag&#xff1a;运营商名称标识符&#xff0c;也是用于标识运营商的一个名称。客户需求描述常用名词&#xff0c;对开发而言都是SPN/PLMN功能模块的内容&#xff0c;状态栏左上角的运营商名称显示。 SPN相关文章&#xff1a; 【笔记】SPN和…

nyist_acm 个人积分赛1(部分题解会补充)

Mirrored String II 看到题解说是马拉车算法&#xff0c;我赛时并没想到&#xff08;好吧其实我是比赛完才知道有马拉车这个算法&#xff09; 因为字符串的长度只有1000&#xff0c;直接暴力跑其实就可以了&#xff0c;但是要注意的是&#xff1b;回文串有俩种形式&#xff0c…

nginx部署前端工程替代方案gateway

nginx部署前端工程替代方案gateway 有市场要求部署的前端vue工程不使用nginx中间件。想弄国产替代的东方通之类的&#xff0c;公司没有购买该产品&#xff0c;我参考了网上的一些java网关框架&#xff0c;springcloud组件&#xff1a;gateway实现代替。 注意后台都是用java编…

shadertoy 游戏《来自星尘》摇杆复刻

正确的做法应该是上 noise 而不是叠加 sin 波&#xff0c;不过如果不想麻烦的话叠波还是一个不错的选择&#xff1a;整体效果如下&#xff0c;已经非常形似 直接上链接&#xff1a;Shader - Shadertoy BETA float radiusScale 0.9; float variation(vec2 v1, vec2 v2, float …

据说这是最细滴,Python接口自动化测试数据驱动DDT使用实战,有这一篇就完全足够了

前言 环境准备 首先&#xff0c;需要安装ddt模块 pip install ddt调用时标准格式 在类下面如下写上&#xff1a;ddt.ddt 在调用的方法下面需要写上&#xff1a;ddt.data(需要传入的多组数据) DDT简单介绍 名称&#xff1a; Data-Driven Tests&#xff0c;数据驱动测试。 作用…

深入理解Servlet

目录&#xff1a; ServletWeb开发历史Servlet简介Servlet技术特点Servlet在应用程序中的位置Tomcat运行过程Servlet继承结构Servlet生命周期Servlet处理请求的原理Servlet的作用HttpServletRequest对象HttpServletResponse对象ServletContext对象ServletConfig对象Cookie对象与…

Keepalived实验

一、 LVSKeepalived 实验&#xff1a;7-1为主&#xff1b; 7-2为备&#xff1b; 7-3和7-4为后端服务器 1.关闭防火墙和selinux [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 02.配置主设备7-1 1.安装ipvsadm和keepalived [rootlocalhost ~]#…

阿珊解说Vue中`$route`和`$router`的区别

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

可视化图表:柱坐标系与对应图表详解

一、柱坐标系及其构成 柱状坐标系是一种常见的可视化图表坐标系&#xff0c;用于显示柱状图&#xff08;也称为条形图&#xff09;的数据。它由两个相互垂直的轴组成&#xff0c;一个是水平轴&#xff08;X轴&#xff09;&#xff0c;另一个是垂直轴&#xff08;Y轴&#xff0…

评测本地部署的语音识别模型

1 引言 最近&#xff0c;朋友给我发来了一段音频&#xff0c;想转录成文字&#xff0c;并使用大型润色文本。音频中的普通话带有一定的口音&#xff0c;并且讲解内容较为专业&#xff0c;所以一般的语音识别工具很难达到较高的识别率。 于是试用了两个大模型。Whisper 是目前…

AIOps常见问题

AIOps的自动化通常指什么&#xff1f; AIOps 平台的自动化一般包括以下几个方面&#xff1a; 数据收集和整合&#xff1a;AIOps 平台可以从多个 IT 基础架构组件、应用需求与性能监视工具以及服务工单系统等数据源中收集并整合运维数据&#xff0c;形成一个全面的数据平台。数…

Access AR Foundation 5.1 in Unity 2022

如果已经下载安装了ARF但版本是5.0.7 可以通过下面的方式修改 修改后面的数字会自动更新 更新完成后查看版本 官方文档 Access AR Foundation 5.1 in Unity 2021 | AR Foundation | 5.1.2

YOLOv9中train.py与train_dual.py的异同!

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 首先&#xff0c;train.py&#xff08;左&#xff09;与train_dual.py(右)中的损失函数是不一样的&#xff0c;这也解释了为什么使用train.py除了填入…

Visual Studio 2022之Release版本程序发送到其它计算机运行

目录 1、缺少dll​ 2、应用程序无法正常启动 3、This application failed to start because no Qt platform plugin could be initialized. 代码在Debug模式下正常运行&#xff0c;然后切换到Release模式下&#xff0c;也正常运行&#xff0c;把第三方平台的dll拷贝到exe所在…