C/C++编程:从0到1学习libuv(linux、Clion)

2023-11-02

libuv强制使用异步和事件驱动的编程风格。它的核心工作是提供一个event-loop,还有其他基于IO和其他事件通知的回调函数。libhv还提供了一些核心工具,比如定时器,非阻塞的网络支持,异步文件系统访问,子进程等

实践

接下来我们安装这个程序

https://github.com/libuv/libuv

README.md里,我们就可以在Build Instructions找到安装方法

下载地址

$ tar -xvf libuv-v1.9.1.tar.gz
$ sh autogen.sh
+ libtoolize --copy
autogen.sh:43: libtoolize: 未找到命令
$  yum install libtool
$ ./configure
$ make
$ make check
[%  96|+ 273|-   1|T   0|S   2]: thread_stack_size
`thread_stack_size` skipped
Output from process `thread_stack_size`:
OSX only test
=============================================================
[% 100|+ 282|-   1|T   0|S   3]: Done.
FAIL: test/run-tests
======================================================
1 of 1 test failed
Please report to https://github.com/libuv/libuv/issues
======================================================
make[1]: *** [check-TESTS] 错误 1
make[1]: 离开目录“/home/oceanstar/CLionProjects/libuv-v1.9.1”
make: *** [check-am] 错误 2

$ make install

在事件驱动编程中,程序会关注每一个事件,并且对每一个事件的发生做出反应。libuv会负责将来自操作系统的事件收集起来,或者监视其他来源的事件。这样,用户就可以注册回调函数,回调函数将会在事件发生的时候被调用。event-loop会一直保持运行的状态。用伪代码描述如下:

while there are still events to process:
    e = get the next event
    if there is a callback associated with e:
        call the callback

event-loop最终会被uv_run()启动-:当使用libuv时,最后都会调用uv_run()

系统编程最经常处理的一般是输入和输出,而不是一大堆数据处理。问题在于传统的输入、输出函数(比如readfprintf)都是阻塞的。实际上,系统IO操作比CPU慢太多,如果任务没有完成,函数是不会返回的,所以程序在这段时间内什么都做不了。对于需要高性能的程序来说,这是一个主要的障碍因为其他活动和I/O操作都在保持等待。

其中一个标准的解决方案是使用多线程。每一个阻塞的IO操作都会被分配到各个线程中(或者线程池)。当某个线程一旦阻塞,处理器就可以调度处理其他需要CPU资源的线程。

但是libuv使用了另外一个解决方案,那就是异步,非阻塞风格。大多数的现代操作系统提供了基于事件通知的子系统。例如,一个正常的socket上的read调用会发生阻塞,直到发送方把信息发送过来。但是,实际上程序可以请求操作系统监视socket事件的到来,并将这个事件通知放到事件队列中。这样,程序就可以很简单地检查事件是否到来(可能此时正在使用cpu做数值处理的运算),并及时地获取数据。

  • 说libuv是异步的,是因为程序可以在一头表达对某一事件的兴趣,并在另一头获取到数据(对于时间或是空间来说)
  • 它是非阻塞是因为应用程序无需在请求数据后等待,可以自由地做其他的事

让我们开始写第一个libuv程序吧!它什么都没做,只是开启了一个loop,然后很快地退出了。
在这里插入图片描述

cmake_minimum_required(VERSION 3.16)
project(libuv_test C)

set(CMAKE_C_STANDARD 99)
link_directories(usr/local/lib)
include_directories(usr/local/include)

add_executable(${PROJECT_NAME}  main.c)

target_link_libraries (${PROJECT_NAME} -luv )   #libuv.a 
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main() {
    uv_loop_t *loop = malloc(sizeof(uv_loop_t));
    uv_loop_init(loop);

    printf("Now quitting.\n");
    uv_run(loop, UV_RUN_DEFAULT);

    uv_loop_close(loop);
    free(loop);
    return 0;
}

运行,出错了:

错误: error while loading shared libraries: libuv.so.1: cannot open shared object file: No such file or directory

原因:ld提示找不到库文件,而库文件就在/usr/local/lib目录下。
链接器ld默认的目录是/lib/和/usr/lib,如果放在其他路径也可以,需要让ld知道库文件在哪里。

解决:

在/etc/ld.so.conf.d/目录下新建任何以.conf为后缀的文件,如

$sudo vim libuv.conf

内容如下:

/usr/local/lib

运行,如下命令,以更新/etc/ld.so.cache文件;

sudo ldconfig

继续运行:

在这里插入图片描述
我们可以发现程序很快就退出了,因为没有可以处理的事件。我们可以使用各种API函数来告诉event-loop我们要监视的事件。

  • 从libuv的1.0版本开始,用户可以在使用uv_loop_init之前,给其分配相应的内存。我们可以使用自定义的内存管理方法
  • 记住要使用uv_loop_close(uv_loop_t *)关闭loop,然后再回收内存空间
  • 可以使用uv_default_loop获取libuv提供的默认loop。如果你只需要一个loop的话,可以使用这个。

libevent、libev、libuv

  • libevent :名气最大,应用最广泛,历史悠久的跨平台事件库
  • libev :较 libevent 而言,设计更简练,性能更好,但对 Windows 支持不够好;
  • libuv :开发 node 的过程中需要一个跨平台的事件库,他们首选了 libev,但又要支持Windows,故重新封装了一套,linux 下用 libev 实现,Windows 下用 IOCP 实现;

优先级:

  • libevent:激活的事件组织在优先级队列中,各类事件默认的优先级是相同的,可以通过设置事件的优先级使其优先被处理

  • libev:也是通过优先级队列来管理激活的时间,也可以设置事件优先级

  • libuv:没有优先级概念,按照固定的顺序访问各类事件

资料

两个重要的libuv学习库
https://github.com/nikhilm/uvbook
翻译的libuv的中文教程
https://github.com/luohaha/Chinese-uvbook

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C/C++编程:从0到1学习libuv(linux、Clion) 的相关文章

随机推荐

  • JavaScript-冻结对象

    文章目录 1 冻结对象 2 冻结判断 3 深冻结和浅冻结 1 冻结对象 Object freeze use strict let initialData a 123 initialData a 234 console log initial
  • 极链科技目标检测获Open Images第一,ECCV 2020挑战赛第二

    近日 极链科技在Google AI推出的2020 Open Images Challenge大规模目标检测竞赛和国际顶会ECCV 2020 VIPriors挑战赛目标检测赛道中分别获得第一名 第二名的佳绩 目标检测算法是计算机视觉任务中的重
  • Echarts 监听鼠标右键或者双击

    1 监听 contextmenu 官方文档 注意切换引用控件所对应版本的文档 ECharts 中的事件和行为 引用官方文档示例代码 基于准备好的dom 初始化ECharts实例 var myChart echarts init docume
  • Midjourney AI绘画工具使用保姆级教程

    系列文章目录 之后补充 文章目录 系列文章目录 写在前面 一 Midjourney是什么 二 使用步骤 1 完成Discord注册 2 打开Midjourney官网 3 开始画图 后记 写在前面 据悉 自3月30日 Midjourney已叫
  • sql语句中使用in、not in 查询时,注意条件范围中的null值处理事项

    emp表中的数据 1 使用in的时候 忽略为null的 不会查询出comm为null的数据 select from emp e where e comm in 300 500 null 2 使用not in的时候 如果 not in后面的选
  • CSS基础学习--26 渐变(Gradients)

    CSS3 渐变 gradients 可以让你在两个或多个指定的颜色之间显示平稳的过渡 以前 你必须使用图像来实现这些效果 但是 通过使用 CSS3 渐变 gradients 你可以减少下载的时间和宽带的使用 此外 渐变效果的元素在放大时看起
  • AcWing 897. 最长公共子序列(线性dp)

    题目链接 点击查看 题目描述 给定两个长度分别为 N 和 M 的字符串 A 和 B 求既是 A 的子序列又是 B 的子序列的字符串长度最长是多少 输入输出格式 输入 第一行包含两个整数 N 和 M 第二行包含一个长度为 N 的字符串 表示字
  • 如何用css实现带√三角形

    简介 最近切页面切到一个类似于京东plus会员的页面 当时刚拿到页面的时候人都有些懵 毕竟我是一个前端小白 这种电商的页面还没有这么做过 参考页面 后来经过一段时间的学习发现css的伪类很强大 下面是实现背景加三角形内含 的代码 selec
  • unity单例模板

    Unity 单例模板类 unity 不继承Mono的单例模板 代码片段 unity 不继承Mono的单例模板 代码片段 public class BaseManager
  • Java内嵌数据库Derby 语法(3)

    主键 唯一键包含索引 主键包含唯一键 索引 非空 唯一键包含索引 可空或非空 数据库需要与执行服务的在同个目录下 唯一键 create table app tyu primarykey int primary key com no int
  • 无人驾驶汽车系统入门(十三)——正态分布变换(NDT)配准与无人车定位

    无人驾驶汽车系统入门 十三 正态分布变换 NDT 配准与无人车定位 定位即确定无人车在这个世界中的哪个位置 是无人驾驶技术栈中必不可少的一部分 对于无人车而言 对定位的要求极高 一般情况下 我们希望我们的无人车能够达到 厘米级 的定位精度
  • 【数据结构 C语言版】树,二叉树,线索二叉树,哈夫曼树

    树的概念 根 如下图中 树形结构的 A 子树 每个节点下又称为一棵子树 如 B 为 A 的子树 在一棵树中 节点被定义为他的每一个 子树 根节点的前驱 而他每一个子树的根节点就是他的后继 在描述属性树形结构时 人们往往使用家族称谓 如 把
  • Mysql - 为啥不建议UUID当主键

    1 不能当主键的原因 MySQL写入数据时 会把数据存放到索引页中 使用UUID作为主键 新行的主键值不一定比之前的主键值大 所以innoDb无法做到总是把新行插入到索引的最后 而需要为新行寻找合适的位置来分配新的空间 因为是B 树方式存储
  • 本周 RocektMQ社区活动

    本周 RocektMQ社区邀请了陈厚德老师进行源码直播分享 陈老师曾就职于腾讯 盛大 斗鱼等知名互联网公司 现就职于尚德机构 分享相关信息 直播方式 钉钉群直播方式 群号 21791227 分享题目 RocketMQ同步 异步刷盘机制 分享
  • 微信小程序日历签到,拿走即用~

    参考了小友那个谁的 具体也忘记了 改be改be即用了 因为是日历 里面有一个算空格的地方 嘻嘻 也是小友提供的 再次感谢 html
  • AngularJS 1.4.6 实践 一 —— 单页应用登录验证

    AngularJS 1 4 6 实践 一 单页应用登录验证 一 多视图路由及路由嵌套 1 多视图路由 2 路由嵌套 二 路由检测登录状态 1 添加路由改变监听事件 2 非常重要 解决未知路径无限循环 三 整体代码 1 index html
  • Mysql的SQL语句优化和事务隔离级别

    文章目录 安装步骤 mysql连接命令 优化 事务4种特性和4种级别 脏读 不可重复读 幻读 安装步骤 我的文章 https blog csdn net UnicornRe article details 117657298 mysql连接
  • Python读取Access数据库基本操作

    接上篇 python操作Access mdb数据库环境配置 配置好的环境 进行Access数据库基本的操作 导入模块 import pypyodbc import win32com client path r C Users Adminis
  • Parasoft Jtest 2023.1版本-全新的Jtest让你的Java测试更加容易

    测试用例的创建和执行以及测量代码覆盖率是现代开发过程的重要组成部分 新发布的Parasoft Jtest 2023 1增加了重要的新功能 使Java开发和QA团队在测试实践中更具有生产力和效率 通过使用最新版本的Jtest 您可以在Visu
  • C/C++编程:从0到1学习libuv(linux、Clion)

    libuv强制使用异步和事件驱动的编程风格 它的核心工作是提供一个event loop 还有其他基于IO和其他事件通知的回调函数 libhv还提供了一些核心工具 比如定时器 非阻塞的网络支持 异步文件系统访问 子进程等 实践 接下来我们安装