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) 的相关文章

  • dup2() 和 exec()

    include
  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 如何更改 Kubernetes 中的文件系统观察程序限制 (fs.inotify.max_user_watches)

    我在用着pm2 https github com Unitech pm2查看保存我的应用程序服务器的 NodeJS 程序源代码的目录 该程序在 Kubernetes 集群中运行 但是 我收到此错误 ENOSPC System limit f
  • 在目标 VS 安装时,VSIX 扩展内部使用的 WPF-Log4Net 未输出日志

    当 Log4net 在 VSIX 扩展中使用并安装在另一个目标 VS 上时 它不会记录日志 我有一个 WPF 解决方案 我下载了 log4net dll 添加了 log4net config 并将 复制到输出目录 值设置为 始终复制 log
  • 我的 WPF 应用程序未触发 MainWindow_Loaded

    我目前正在关注Pluralsight C Fundamentals Part 1并在Classes and Objects视频部分指导我在 Visual Studio 中创建一个新的 WPF 应用程序并填写代码 这导致以下结果 namesp
  • 以编程方式运行 T4 文本模板

    有没有一种方法可以通过代码以编程方式运行 T4 文本模板 我正在制作一种自定义域特定语言 我希望相关的文本模板在用户每次保存时运行 目前 这就是我在 DSL 模型中所做的事情 protected override void OnDocume
  • ASP.NET中如何访问除wwwroot以外的位置

    我可以使用访问服务器的物理位置Server MapPath 这给了我内部的物理路径wwwroot文件夹 我想将一些数据保存到同一服务器的另一个驱动器中D 驾驶 我想我无法获取以下位置的物理位置D 驾驶使用Server MapPath因为它位
  • 将授权标头添加到 Web 参考

    我正在尝试向客户端的网络服务发出请求 我不知道客户端的底层平台 我使用 添加 Web 引用 在 Visual Studio 2010 中使用了客户端的 WSDL 并生成了我的代理类 称为 ContactService 我现在需要将如下所示的
  • 为什么 httpRuntime targetFramework="4.5" 禁止抓取 .ASPXAUTH cookie?

    当我的 web config 具有以下 httpRuntime 时 我的控制器无法获取 cookie ASPXAUTH 它似乎能够获取任何其他 cookie 无论带或不带句点前缀 如果我删除下面的行 它就可以正常工作
  • 为什么我无法调试动态加载的程序集?

    我正在开发一个 Web API 项目 该项目使用内部模拟框架 允许拦截和修改来自控制器的响应 它使用 MEF 加载包含某些先决条件匹配时执行的代码的程序集 我知道这是正常工作的 因为我可以在响应中看到模拟已被执行 但由于某种原因我无法调试动
  • 从视图模型调用方法的命令

    好吧 我倾向于避免使用命令 因为它们总是让我感到困惑 但我正在进行一个新项目 并且正在尝试正确构建它 并且在我看来没有任何代码隐藏 基本上我现在想做的就是连接一个按钮来触发一个命令 在我的视图模型上执行一些操作 但不知何故 如此简单的事情仍
  • 为什么未到达的 try-catch 块会增加运行时间?

    我目前正在创建自己的容器库 但我已经看到无法访问 if 语句无效 try catch阻止增加运行时间 这是我的测试 Vector cpp template
  • 生成范围 [min,max] 内的随机数 [重复]

    这个问题在这里已经有答案了 我正在使用 C 生成范围 min max 内的整数随机数 我在用 int random int int min int max return min rand max min 但我认为上面的代码适用于范围 min
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • 如何组合||条件语句中的运算符[重复]

    这个问题在这里已经有答案了 代替 if foo 1 foo 5 foo 9 我喜欢将它们组合起来 类似于以下内容 这不起作用 if foo 1 5 9 那可能吗 不幸的是不是 你最好的选择是创建一个扩展方法 public static bo
  • C# 3.0 中自动属性和公共字段的区别

    我无法理解为什么 C 3 0 中存在自动实现的属性语言功能 当你说的时候有什么区别 public string FirstName than public string FirstName get set 因为它们在生成的 IL 代码 和机
  • 用于 nmap 输出的 C++ xml 解析器

    我是 nmap 的新手 我在 nmap 教程中看到 https nmap org book man output html https nmap org book man output html oX 选项可用于获取 xml 格式的 nma
  • 在Framework 4.6项目中使用.net core DLL

    我已经在 net core 2 0 中构建了一个 DLL 现在我想在使用 net 4 6 1 框架的 WinForms 项目中使用它 我可以引用该 dll 但收到 System IO FileLoadException 表示找不到 Syst
  • asp.net mvc GET 请求上的 formcollection 应该为空

    我正在发布一个简单的操作 public void Login FormCollection formCollection 即使查询字符串值很少 formcollection Count is 0 是靠行为吗 FormCollection 使
  • DataGridView 捕获用户行选择

    我在处理选择时遇到问题DataGridView 我的网格视图包含一个金额列 表单上有一个文本框 应显示所选网格视图行的总数 因此 我需要在用户选择 取消选择 gridview 行时捕获事件并相应地计算 添加 减去 金额 我找到了两种方法 使

随机推荐

  • 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还提供了一些核心工具 比如定时器 非阻塞的网络支持 异步文件系统访问 子进程等 实践 接下来我们安装