Linux 异步 IO 之 Native AIO

Linux Native AIO

来看看 Linux 提供的 AIO 系统调用(自行封装的头文件 native_aio.h):

#ifndef __NATIVE_AIO_H__
#define __NATIVE_AIO_H__

#define _GNU_SOURCE

#include <unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <linux/aio_abi.h>

static inline int io_setup(unsigned nr_events, aio_context_t* ctx_idp)
{
    return syscall(__NR_io_setup, nr_events, ctx_idp);
}

static inline int io_destroy(aio_context_t 

阅读全文…

Linux 异步 IO 之 POSIX AIO

先来看一个简单的读写文件程序,程序读取源文件,然后把内容打印到屏幕上:

#include <unistd.h>
#include <fcntl.h>

#define BUFSIZE 4096

int main(void)
{
    int fd, nbytes;
    char buf[BUFSIZE];

    fd = open(__FILE__, O_RDONLY);
    while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
        write(1, buf, nbytes);

    close(fd);
    return 0;
}

在这个例子中的 read()/write() 都是同步阻塞 IO,即如果没有数据可读或写入未完成时当前线程会一直等待,直到读写操作完成或出错才会返回。

同步 …

阅读全文…

C++11 之变长参数模板

C++ 中可以对函数重载,即同样的函数名字(其实在编译期还是会被生成不同的名字)可以有不同的参数列表,例如 STL 中 string 的构造函数:

string();
string (const string& str);
string (const string& str, size_t pos, size_t len = npos);
string (const char* s);
string (const char* s, size_t n);
...

看上去和 C 中的变长参数有点类似:

void func(int nil, ...);

有点不同的是,C …

阅读全文…

PostgreSQL 笔记

PostgreSQL 是一个采用 BSD 许可证分发的跨平台的对象关系模型数据库,最早可以追溯到 1982 年在伯克利开始的 Ingres 计划。PostgreSQL 出现的时间比 MySQL 要早,之前也听过 PostgreSQL 的大名,不过看到相关的讨论比较少。由于这里的实验需求远未达到两者的极限,所以也没什么评测,网上的评价就不搬运过来了,有兴趣的可以搜一下。这里的实验环境是 Debian 6,PostgreSQL 版本是 9.1。

初始化

不同于 MySQL 在安装的时候会被要求输入 root 的密码,安装 PostgreSQL 的时候什么提示都没有,装完之后也不知道该干嘛……在网上搜了一把,照着参考资料 [1] 操作了一遍,基本算是入门了。

由于没有 root 用户,默认有 root 权限的用户名是 postgres,也有同名的数据库。网上有很多介绍初始化的方法都是新建一个 postgres 的用户,然后切换到该用户登录后再修改密码。但是觉得为了初始化新建一个用户有点小题大作了,于是上网搜了下,发现可以通过修改配置文件达到目的。

首先修改 /etc/postgresql/9.1/main/pg_hba.conf,把其中的

local all postgres 

阅读全文…

B 树

1972 年 R. Bayer 和 E. McCreight 的论文(参考资料 [1])提出了 B- 树。B- 树是一棵平衡树,与一般的平衡二叉树(AVL,红黑树等)不同的是,B- 树的每个节点最多可以拥有 m(m>=2)个元素,(m+1)个子节点,并且所有的叶子节点位于同一层。B- 树的查找和插入的时间复杂度和二叉树一样,都是 O(logn),但因为每个节点保存的元素比较多(一般是几十个到几百个之间),树的高度比一般的二叉树要小很多,访问硬盘次数更少,在数据不能全部加载到内存的时候比一般的二叉树效率要好。

定义

一棵最多有 2n+1 个元素(其中 n>= 1)的 B- 树的定义如下(参考资料 [2, 3]):

  • 每个节点最多有 2n+1 个元素;
  • 每个非叶子节点(根节点除外)至少有 n+1 棵子树;
  • 如果根节点不是叶子节点,则至少有 2 棵子树;
  • 一个有 k 棵子树的非叶子节点有 k-1 个元素,按升序排列;

阅读全文…

Linux 异步 IO 之 epoll

epoll 是 Linux 内核在 2.5 引入的一个 I/O 事件通知机制,用来取代旧的 select(2) 和 poll(2)。

select() 的工作模式

从通知机制上说,select() 的方式和 epoll 的方式类似,都是阻塞在某个函数上,如果有指定的 I/O 事件发生的话函数就会返回。这样的通知机制的好处在于,在没有事件发生的时候系统可以去干别的事情。不过 select() 只告诉你有事件发生了,但是没有说清楚是哪些 fd 触发了事件通知,你需要去遍历所有的 fd 来找出哪些真正需要处理。select() 的函数原型如下:

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

fd_set 是一个 …

阅读全文…

使用 C 编写 Lua 模块

Lua 作为一种小巧的语言,一般都是嵌入到 C/C++ 中作为扩展语言,但是也可以作为独立的脚本语言使用,并且可以使用 C/C++ 编写扩展模块。在参考资料 [1] 中有怎样用 C/C++ 编写模块的介绍,但是比较零散,也不是很详细,所以在这里整理一下。

这里使用的 Lua 版本是 5.2.3,系统是 Debian 7。

Hello, world!

不废话,还是先看一下经典的 "Hello, world!" 例子。

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

static int l_hello(lua_State* l)
{
    printf("Hello, world!\n");
    return 0;
}

static const 

阅读全文…

sicp 笔记 (11)

第四章习题 4.16 - 4.37 的解答。

E-4.16:

(a) 如果匹配到相应的变量再检查一下变量值是否为“unassigned”。

(define (lookup-variable-value var env)
  (define (env-loop env)
    (define (scan vars vals)
      (cond ((null? vars)
             (env-loop (enclosing-environment env)))
            ((eq? var (car vars))
             (let ((v (car vals)))
               (if (eq? v '*unassigned*)
                 (error 

阅读全文…