当前位置: 首页 > news >正文

linux C -glib库的基本使用

一、课程介绍

GLiblibuv。这两个库分别代表了传统 GNOME 生态与现代异步网络编程的两种风格,是从底层走向工程实践的重要桥梁。


二、库概览与跨平台原理

2.1 GLib 简介

GLib 是 GNOME 项目的底层公共库,提供标准化的 API,包括内存管理、数据结构、线程、日志等内容,封装了大量原始系统调用,使开发更安全、跨平台。

适合人群: 需要在 Linux/Windows 上编写后台逻辑、跨平台桌面程序等。

常见用途:

  • GTK 应用开发

  • 跨平台 CLI 工具

  • 线程安全的数据结构封装

GLib 特点(重难点):

  • 跨平台性强:抽象系统调用,支持 Windows/Linux

  • 面向对象思维:虽为 C 语言实现,但具备类、信号、对象等机制(通过 GObject)

  • 丰富的数据结构库:如链表、哈希表、队列,全部线程安全版本

  • 线程模型完整:GThread、GMutex、GCond 等,适配 C11 pthread

  • 灵活的事件循环GMainLoopGSource 适合写任务调度器

  • 日志和测试内建g_logg_test 提高可维护性

使用 GLib 可能遇到的难点:

  • 函数名长、类型多,初期记忆成本高

  • 不熟悉宏、类型系统(如 gpointergchar)时调试困难

  • 手动内存释放仍然需要注意(如 g_free, g_strfreev

2.2 libuv 简介

libuv 是一个跨平台的异步 IO 库,广泛用于 Node.js、Luvit 等项目中,以事件驱动的方式处理网络、文件、线程等任务,性能极高。

适合人群: 有服务端开发或并发性能需求的开发者。

常见用途:

  • 网络服务器

  • CLI 工具中的文件/事件监听

  • 跨平台异步框架的底层支撑

libuv 特性与重难点:

  • 事件驱动模型:IO 不阻塞,函数立即返回,通过回调处理完成事件(Reactor 模式)

  • 跨平台统一接口:隐藏复杂平台差异,开发体验一致(例如 IOCP vs epoll)

  • 线程池支持:适合 CPU 密集或阻塞 IO,通过 uv_queue_work 调用

  • 高度模块化:所有功能以 uv_*_t 结构为中心,便于理解生命周期

  • 性能优越:大量 Node.js 实践验证

学习难点:

  • 需要理解事件驱动编程范式,与传统同步方式不同

  • 回调嵌套逻辑较深,调试复杂

  • 每个模块初始化结构体略显繁琐(需严格遵循 init/start/run

2.3 跨平台机制

  • GLib:使用宏如 G_OS_WIN32G_OS_UNIX 和统一封装函数,如 g_thread_create() 对应 pthread 或 Windows thread

  • libuv:用 CMake + 条件编译封装 epoll/kqueue/IOCP/IOURING 等底层系统调用


三、GLib 使用详解

GLib 的设计思路是将复杂系统调用抽象为统一接口,大大提升可移植性。

3.1 GLib 模块结构图

 +--------------------+|     glib.h        |+--------------------+|+----+----+--------------------+|         |                    |+------+  +--------+     +-----------------+|GList |  |GThread| ... |GMainLoop/GSource|+------+  +--------+     +-----------------+↑           ↑                  ↑数据结构    线程控制        事件/异步处理

3.2 内存管理与基本类型

GLib 定义了很多基础类型:

  • gint/guint:有符号/无符号 int

  • gchar:char

  • gboolean:布尔类型(TRUE/FALSE

内存申请与释放:

#include <glib.h>int main() {gchar *name = g_strdup("Hello"); // 复制字符串(分配内存)g_print("%s\n", name);g_free(name); // 释放内存return 0;
}

3.3 字符串操作

GLib 提供了 GString 类型,支持动态字符串(类似 C++ std::string):

GString *str = g_string_new("Hello");
g_string_append(str, " World");
g_print("%s\n", str->str);
g_string_free(str, TRUE);

也可以使用常用函数:

  • g_ascii_strcasecmp() 比较大小写无关

  • g_strsplit() 拆分字符串

  • g_strjoinv() 拼接字符串数组


3.4 数据结构

GList / GSList

#include <glib.h>GSList *list = NULL;
list = g_slist_append(list, "apple");
list = g_slist_append(list, "banana");for (GSList *l = list; l != NULL; l = l->next) {g_print("%s\n", (gchar*)l->data);
}
g_slist_free(list);

GHashTable

GHashTable *map = g_hash_table_new(g_str_hash, g_str_equal);
g_hash_table_insert(map, "name", "Alice");
g_print("name = %s\n", g_hash_table_lookup(map, "name"));
g_hash_table_destroy(map);

3.5 多线程与线程池

GLib 支持跨平台线程封装:

void* worker(gpointer data) {g_print("Worker thread: %s\n", (gchar*)data);return NULL;
}g_thread_new("my-thread", worker, "hello from thread");
g_usleep(100000);

线程池:

GThreadPool *pool = g_thread_pool_new(worker, NULL, 4, FALSE, NULL);
g_thread_pool_push(pool, "task1", NULL);
g_thread_pool_free(pool, FALSE, TRUE);

3.6 日志与调试

GLogLevelFlags level = G_LOG_LEVEL_WARNING;
g_log("MyApp", level, "This is a warning message.");

你可以设置自定义日志处理器:

void my_logger(const gchar *log_domain, GLogLevelFlags level, const gchar *message, gpointer user_data) {g_print("[LOG] %s\n", message);
}g_log_set_handler("MyApp", G_LOG_LEVEL_MASK, my_logger, NULL);
g_log("MyApp", G_LOG_LEVEL_INFO, "Started application");

3.7 单元测试

使用 glib.hglib/gtestutils.h

#include <glib.h>void test_addition() {g_assert_cmpint(2 + 2, ==, 4);
}int main(int argc, char **argv) {g_test_init(&argc, &argv, NULL);g_test_add_func("/math/add", test_addition);return g_test_run();
}

接下来可继续图示 GLib 的事件循环(GMainLoopGSource),以及集成到网络事件驱动中。


3.7 GLib 事件循环概念(图示)

GLib 的事件循环是实现异步任务的核心机制。

  • GMainContext 管理所有事件源,负责监听和分发事件

  • GMainLoop 是事件循环本体,调用 g_main_context_iteration() 驱动事件执行

  • GSource 代表一个具体事件源,绑定回调函数执行具体任务

事件循环使用示例


#include <glib.h>
#include <stdio.h>gboolean timeout_callback(gpointer data)
{printf("Timeout happened!\n");GMainLoop *loop = (GMainLoop *)data;g_main_loop_quit(loop); // 退出循环return FALSE;           // 只触发一次
}int main()
{GMainLoop *loop = g_main_loop_new(NULL, FALSE);g_timeout_add_seconds(1, timeout_callback, loop);g_main_loop_run(loop);g_main_loop_unref(loop);return 0;
}

四、libuv 使用详解

libuv 是一个跨平台的异步 IO 库,事件驱动模型的代表。

4.1 libuv 事件循环模型

libuv 的事件循环是它的核心设计思想,所有异步操作都必须通过 uv_run() 驱动执行:

uv_loop_t *loop = uv_default_loop(); uv_run(loop, UV_RUN_DEFAULT);

  • uv_loop_t 是事件循环结构体,内部封装了定时器、IO、信号等子模块

  • uv_run 会阻塞当前线程,直到所有异步事件处理完毕(或主动关闭)

  • 所有 handle(如 socket、timer)必须 attach 到 loop 上

定时器示例

#include <uv.h>
#include <stdio.h>void timer_cb(uv_timer_t *handle)
{printf("Timer triggered!\n");uv_stop(uv_default_loop());
}int main()
{uv_timer_t timer;uv_timer_init(uv_default_loop(), &timer);uv_timer_start(&timer, timer_cb, 1000, 0); // 延迟1000ms执行uv_run(uv_default_loop(), UV_RUN_DEFAULT);return 0;
}

4.2 异步 TCP 通信

libuv 通过 uv_tcp_tuv_connect_t 和回调机制完成跨平台 TCP 通信。

基本流程:

  • 初始化 uv_loop_tuv_tcp_t

  • 发起连接或监听

  • 通过回调处理连接、数据读写事件

4.3 线程池与异步任务

libuv 内置线程池用于执行阻塞任务,避免主事件循环阻塞。

#include <uv.h>
#include <stdio.h>void work_cb(uv_work_t *req)
{// 这里执行耗时任务
}void after_work_cb(uv_work_t *req, int status)
{printf("Work done!\n");
}int main()
{uv_work_t req;uv_queue_work(uv_default_loop(), &req, work_cb, after_work_cb);uv_run(uv_default_loop(), UV_RUN_DEFAULT);return 0;
}
http://www.lryc.cn/news/598674.html

相关文章:

  • Windows环境下 Go项目迁移至Ubuntu(WSL) 以部署filebeat为例
  • 如何在 Ubuntu 24.04 服务器或桌面版上安装和使用 gedit
  • 深度分析Java内存回收机制
  • 跨境支付入门~国际支付结算(电商篇)
  • unordered_map和unordered_set特性以及解决哈希冲突
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-19,(知识点:PCB布局布线的设计要点)
  • DevOps 完整实现指南:从理论到实践
  • LeetCode 23:合并 K 个升序链表
  • 【已解决】YOLO11模型转wts时报错:PytorchStreamReader failed reading zip archive
  • 医疗AI轻量化部署方案的深度梳理与优化路径判研
  • 基于Qt的仿QQ聊天系统设计
  • Ethereum: 区块链浏览器,我们的“天眼”
  • 力扣 hot100 Day54
  • 【开源】WpfMap:一个基于WPF(Windows Presentation Foundation)技术构建的数据可视化大屏展示页面
  • JS对象键的秘密:数字变字符串?
  • 【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构
  • 应急响应】Linux 自用应急响应工具发版 v6.0(LinuxGun)
  • redis 源码阅读
  • 完整指南:使用Apache htpasswd为Chronograf配置基础认证及功能详解
  • AWS S3 生命周期管理最佳实践:IoT Core 日志的智能存储优化
  • 【水文水资源] SWAT、AquaCrop模型、HYPE、Aquatox、Delft3D、FVCOM、3s水文、
  • 数据推荐丨海天瑞声7月数据集上新啦!
  • 用python自动标注word试题选项注意事项
  • 基于k2-icefall实践Matcha-TTS中文模型训练2
  • 机器学习概述与 KNN 算法详解
  • 湖北大数据集团赴OpenCSG三峡传神社区调研指导
  • 虚拟电厂——解读69页 2024虚拟电厂售电业务及共享储能等新型业态趋势【附全文阅读】
  • YOLO11有效涨点优化:注意力魔改 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测
  • 深入解析文件操作(下)- 文件的(顺序/随机)读写,文件缓冲区,更新文件
  • 模块化商城的快速部署之道:ZKmall开源商城如何让电商功能即插即用