basics_of_libuv
Basics of libuvlibuv强制使用异步和事件驱动的编程风格。它的核心工作是提供一个event-loop,还有基于I/O和其它事件通知的回调函数。libuv还提供了一些核心工具,例如定时器,非阻塞的网络支持,异步文件系统访问,子进程等。 Event loops在事件驱动编程中,程序会关注每一个事件,并且对每一个事件的发生做出反应。libuv会负责将来自操作系统的事件收集起来,或者监视其他来源的事件。这样,用户就可以注册回调函数,回调函数会在事件发生的时候被调用。event-loop会一直保持运行状态。用伪代码描述如下: 1234while there are still events to process: e = get the next event if there is a callback associated with e: call the callback 举几个事件的例子: 准备好被写入的文件。 包含准备被读取的数据的socket。 超时的定时器。 event-loop最终会被uv_ru...
advanced-event-loops
Advanced event loopslibuv提供了非常多的控制event-loop的方法,你能通过使用多loop来实现很多有趣的功能。你还可以将libuv的event loop嵌入到其它基于event-loop的库中。比如,想象着一个基于Qt的UI,然后Qt的event-loop是由libuv驱动的,做着加强级的系统任务。 Stopping an event loopuv_stop()用来终止event loop。loop会停止的最早时间点是在下次循环的时候,或者稍晚些的时候。这也就意味着在本次循环中已经准备被处理的事件,依然会被处理,uv_stop不会起到作用。当uv_stop被调用,在当前的循环中,loop不会被IO操作阻塞。上面这些说得有点玄乎,还是让我们看下uv_run()的代码: src/unix/core.c - uv_run123456789101112131415161718192021int uv_run(uv_loop_t* loop, uv_run_mode mode) { int timeout; int r...
filesystem
Filesystem简单的文件读写是通过uv_fs_*函数族和与之相关的uv_fs_t结构体完成的。 note libuv 提供的文件操作和 socket operations 并不相同。套接字操作使用了操作系统本身提供了非阻塞操作,而文件操作内部使用了阻塞函数,但是 libuv 是在线程池中调用这些函数,并在应用程序需要交互时通知在事件循环中注册的监视器。 所有的文件操作函数都有两种形式 - 同步**(synchronous)** 和 异步**( asynchronous)**。 同步方式如果没有指定回调函数则会被自动调用( 并阻塞),函数的返回值是libuv error code 。但以上通常只对同步调用有意义。而异步方式则会在传入回调函数时被调用, 并且返回 0。 Reading/Writing files文件描述符可以采用如下方式获得: 1int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) 参数flags与mode...
introduction
Introduction本书由很多的libuv教程组成,libuv是一个高性能的,事件驱动的I/O库,并且提供了跨平台(如windows, linux)的API。 本书会涵盖libuv的主要部分,但是不会详细地讲解每一个函数和数据结构。官方文档中可以查阅到完整的内容。 本书依然在不断完善中,所以有些章节会不完整,但我希望你能喜欢它。 Who this book is for如果你正在读此书,你或许是: 系统程序员,会编写一些底层的程序,例如守护进程或者网络服务器/客户端。你也许发现了event-loop很适合于你的应用场景,然后你决定使用libuv。 一个node.js的模块开发人员,决定使用C/C++封装系统平台某些同步或者异步API,并将其暴露给Javascript。你可以在node.js中只使用libuv。但你也需要参考其他资源,因为本书并没有包括v8/node.js相关的内容。 本书假设你对c语言有一定的了解。 Backgroundnode.js最初开始于2009年,是一个可以让Javascript代码离开浏览...
networking
Networking在 libuv 中,网络编程与直接使用 BSD socket 区别不大,有些地方还更简单,概念保持不变的同时,libuv 上所有接口都是非阻塞的。它还提供了很多工具函数,抽象了恼人、啰嗦的底层任务,如使用 BSD socket 结构体设置 socket 、DNS 查找以及调整各种 socket 参数。 在网络I/O中会使用到uv_tcp_t和uv_udp_t。 note 本章中的代码片段仅用于展示 libuv API ,并不是优质代码的范例,常有内存泄露和未关闭的连接。 TCPTCP是面向连接的,字节流协议,因此基于libuv的stream实现。 server服务器端的建立流程如下: 1.12345678910111213141516171819202122232.```uv_tcp_bind```绑定。 3.```uv_listen```建立监听,当有新的连接到来时,激活调用回调函数。 4.```uv_accept```接收链接。 5.使用stream操作来和客户端通信。 #### tcp-echo-server/main.c -...
processes
Processeslibuv提供了相当多的子进程管理函数,并且是跨平台的,还允许使用stream,或者说pipe完成进程间通信。 在UNIX中有一个共识,就是进程只做一件事,并把它做好。因此,进程通常通过创建子进程来完成不同的任务(例如,在shell中使用pipe)。 一个多进程的,通过消息通信的模型,总比多线程的,共享内存的模型要容易理解得多。 当前一个比较常见的反对事件驱动编程的原因在于,其不能很好地利用现代多核计算机的优势。一个多线程的程序,内核可以将线程调度到不同的cpu核心中执行,以提高性能。但是一个event-loop的程序只有一个线程。实际上,工作区可以被分配到多进程上,每一个进程执行一个event-loop,然后每一个进程被分配到不同的cpu核心中执行。 Spawning child processes一个最简单的用途是,你想要开始一个进程,然后知道它什么时候终止。需要使用uv_spawn完成任务: spawn/main.c12345678910111213141516171819202122232425uv_loop_t *loop;u...
utilities
Utilities本章介绍的工具和技术对于常见的任务非常的实用。libuv吸收了libev用户手册页中所涵盖的一些模式,并在此基础上对API做了少许的改动。本章还包含了一些无需用完整的一章来介绍的libuv API。 Timers在定时器启动后的特定时间后,定时器会调用回调函数。libuv的定时器还可以设定为,按时间间隔定时启动,而不是只启动一次。可以简单地使用超时时间timeout作为参数初始化一个定时器,还有一个可选参数repeat。定时器能在任何时间被终止。 1234uv_timer_t timer_req;uv_timer_init(loop, &timer_req);uv_timer_start(&timer_req, callback, 5000, 2000); 上述操作会启动一个循环定时器(repeating timer),它会在调用uv_timer_start后,5秒(timeout)启动回调函数,然后每隔2秒(repeat)循环启动回调函数。你可以使用: 1uv_timer_stop(&timer_req); 来停止定时器...
threads
Threads等一下!为什么我们要聊线程?事件循环(event loop)不应该是用来做web编程的方法吗?(如果你对event loop, 不是很了解,可以看这里)。哦,不不。线程依旧是处理器完成任务的重要手段。线程因此有可能会派上用场,虽然会使得你不得不艰难地应对各种原始的同步问题。 线程会在内部使用,用来在执行系统调用时伪造异步的假象。libuv通过线程还可以使得程序异步地执行一个阻塞的任务。方法就是大量地生成新线程,然后收集线程执行返回的结果。 当下有两个占主导地位的线程库:windows下的线程实现和POSIX的pthread。libuv的线程API与pthread的API在使用方法和语义上很接近。 值得注意的是,libuv的线程模块是自成一体的。比如,其他的功能模块都需要依赖于event loop和回调的原则,但是线程并不是这样。它们是不受约束的,会在需要的时候阻塞,通过返回值产生信号错误,还有像接下来的这个例子所演示的这样,不需要在event loop中执行。 因为线程API在不同的系统平台上,句法和语义表现得都不太相似,在支持程度上也各不相同。考虑...
SUMMARY
目录 前言 关于封面 关于本书 第1章 你好,C++的并发世界 1.1 何谓并发 1.2 为什么使用并发? 1.3 C++中的并发和多线程 1.4 开始入门 1.5 本章总结 第2章 线程管理 2.1 线程管理的基础 2.2 向线程函数传递参数 2.3 转移线程所有权 2.4 运行时决定线程数量 2.5 标识线程 2.6 本章总结 第3章 线程间共享数据 3.1 共享数据带来的问题 3.2 使用互斥量保护共享数据 3.3 保护共享数据的替代设施 3.4 本章总结 第4章 同步并发操作 4.1 等待一个事件或其他条件 4.2 使用期望等待一次性事件 4.3 限定等待时间 4.4 使用同步操作简化代码 4.5 本章总结 第5章 C++内存模型和原子类型操作 5.1 内存模型基础 5.2 C++中的原子操作和原子类型 5.3 同步操作和强制排序 5.4 本章总结 第6章 基于锁的并发数据结构设计 6.1 为并发设计的意义何在? 6.2 基于锁的并发数据结构 6.3 基于锁设计更加复杂的数据结构 6.4 本章总结 第7章 无锁并发数据结构设计 7.1 定义和意义 ...
D.0-chinese
附录D C++线程库参考














