使用 fuse 编写文件系统 (1)

FUSE 的全称是“Filesystem in Userspace”,即“用户空间的文件系统”,这是一个内核模块,能够让用户在用户空间实现文件系统并且挂载到某个目录,就像在内核实现的文件系统一样。使用 FUSE 有几个好处:一是因为在用户空间实现,开发和调试都比较方便;二是可以把一些常用的服务以文件系统的形式展现,方便操作,如 ftpfs,sshfs,mailfs 等;另外可以避免一些版权问题,如 Linux 上对 ntfs,zfs 的操作都是通过 FUSE 实现的。当然用户空间的实现也有缺点,最明显的就是由多次在用户态/内核态切换带来的性能下降。

根据参考资料 [1] 的介绍,用户通过 FUSE 和内核的通信过程如下:

                   +----------------+
                   | myfs /tmp/fuse |
                   +----------------+
                          |   ^
+--------------+          v   |
| ls /tmp/fuse |    +--------------+
+--------------+    |    libfuse   |
      ^  

阅读全文…

programming in lua (12)

第 9 章和第 30 章部分内容,都是讲线程相关的。

基本概念

lua 中的 coroutine 和我们通常说的“线程”概念相近,但是这里的 coroutine 并不是真正的线程,在某个时刻只有一个 coroutine 在执行。lua 将 coroutine 的所有函数都放在一个叫“coroutine”的 table 中,下面来看一下这些函数。

co = coroutine.create(function () print("hello") end)
print(co) -- thread: 0x11fa810
print(coroutine.status(co)) -- suspended
coroutine.resume(co) -- hello
print(coroutine.status(co)) -- dead

create() 接收一个函数作为参数,创建一个对应的 …

阅读全文…

programming in lua (11)

第 29 章和 31 章。这两章都是讲资源管理的,就放一起看了。

userdata 可能是用户自己分配的一段内存(内存里可能有一个域是文件描述符,可能是一个指向另外一段内存的指针,等等),当这段 userdata 被释放时,其中包含的其它资源也需要被释放(如需要关闭文件,释放另一段内存等)。某些语言提供了一种叫做“finalizer”的机制来完成这件事,在 lua 中对应的是一个“__gc”的域,当某个 userdata 被 lua 回收时,如果它对应的 metatable 中有“__gc”这个域,则这个域所指向的函数(通常指向的是函数)将会被调用,这样用户就能释放和 userdata 相关联的内容。

目录遍历迭代器

第 26 章实现过一个目录遍历的程序,程序每次返回一个包含所有目录项的 table。这里我们将要实现一个迭代器,每次只返回一个目录:

for dname in dir(".") do
    print(dname)
end

c 语言中遍历目录的步骤:首先使用 opendir() 函数打开目录返回一个指向 DIR 结构体的指针,然后使用 readdir() 每次读取一个目录,读取完所有目录后使用 closedir() …

阅读全文…

programming in lua (10)

第 28 章。这章主要是讲怎样在 lua 中使用 c 语言中自定义的数据结构。

先看一个简单的例子:boolean 数组。在 lua 中可以使用 table 来存储,在 c 语言中由于每个变量只占一个 bit,使用的内存只占用 table 实现的 3%。

程序使用如下的数据结构和相关的宏定义:

#include <limits.h>

#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(i)     ((unsigned int)(i) / BITS_PER_WORD)
#define I_BIT(i)      (1 << ((unsigned int)(i) % BITS_PER_WORD))


阅读全文…

sicp 笔记 (1)

“sicp”全称是“Structure and Interpretation of Computer Programs”,是 MIT 计算机专业第一年的一门入门课程的教材(据说现在已经取消了这门课,取而代之的是另一门使用 python 的课程)。网上很多人都强烈推荐这本书,给出了各种赞美之词,因此从网上找了个排版比较好的电子版(google 搜“sicp unofficial texinfo format”,我用的是 2.neilvandyke4 这个版本)。直到研究生快毕业才开始学习别人本科第一年的教材,希望亡羊补牢还不算晚。

这里使用 plt-scheme,除了 1.28 小题的 random 函数之外其它题目都能运行,推荐使用 mit-scheme(debian 中只有 i386 的包,64 位的需要自己到官网下载编译)。

下面是第一章的习题解答部分。

E-1.1: 把内容对着敲一遍就行了

E-1.2:

(/ (+ 5 4 (- 2 (- 3 (+ 

阅读全文…

pthread 学习笔记 (4)

自旋锁

除了前面提到过的互斥锁和读写锁外,还有另外一种锁:自旋锁(spinlock)。自旋锁的原理比较简单,就是当某个资源不可用时不断查询,直到资源可用:

void tese_and_set(bool* condition)
{
    bool tmp = *condition;
    *condition = true;
    return tmp;
}

void func()
{
    while (test_and_set(&condition));

    /* visit */

    condition = false;
}

其中的操作 test_and_set() 可以看成一个原子操作,通常由硬件来实现。如果 condition 为 false,while 循环会不断地查询 condition 的状态,直到其可用为止。因为在条件不满足时程序也一直在忙,这样会消耗 cpu 资源,所以自旋锁适合用在执行时间不长的临界区中,例如修改一个数值等。

由于自旋锁比较简单,pthread …

阅读全文…

hadoop笔记 (4):streaming

hadoop 提供了 3 种方式来实现自己的功能,一种是 java 接口,另一种是 pipes,还有一种是 streaming。streaming 允许用任何语言来开发 mapper 和 reducer,它们和 hadoop 之间的交互通过标准输入/输出来进行。这种方式的好处是调试很方便。

先来看一个使用 bash 编写的 wordcount 的例子:

#!/bin/bash

while read line; do
    arr=($line)
    let i=0
    while ! [ -z ${arr[$i]} ]; do
        echo -e "${arr[$i]}\t1"
        let i=$i+1
    done

阅读全文…

hadoop笔记 (3):pipes例子分析 (2)

使用 partitioner 和 combiner

下面的程序是对 hadoop 1.0.3 自带例子(src/examples/pipes/impl/wordcount-part.cc)的一个修改版:

#include <string>
#include <vector>
using namespace std;

#include <hadoop/Pipes.hh>
#include <hadoop/StringUtils.hh>
#include <hadoop/TemplateFactory.hh>

class WordCountMapper : public HadoopPipes::Mapper {

    public:

        WordCountMapper(HadoopPipes::TaskContext& context) {}

        void map(HadoopPipes::MapContext& context)
        {
            vector<string> words = HadoopUtils::splitString(context.getInputValue(), " 

阅读全文…

hadoop笔记 (2):pipes例子分析 (1)

Pipes 是 hadoop 提供的 c++ 接口,但是在官网上找不到 pipes 的文档,只能从例子开始一点点摸索。实验环境是 debian 6 amd64,hadoop 1.0.3。hadoop 的安装目录是 $HOME/hadoop,安装和配置过程在上一篇安装笔记中有提到。

为了少敲些字符,给 hadoop 命令做了一个 alias:

alias hadoop='$HOME/hadoop/bin/hadoop'

单词统计程序

下面的程序是对 hadoop 1.0.3 自带的单词统计程序(src/examples/pipes/impl/wordcount-simple.cc)的一个修改版:

#include <string>
#include <vector>
using namespace std;

#include <hadoop/Pipes.hh>
#include <hadoop/StringUtils.hh>
#include <hadoop/TemplateFactory.hh>

class WordCountMapper 

阅读全文…

hadoop笔记 (1):安装和配置

记录一下 hadoop 集群的搭建过程,一共 3 台机器,操作系统都是 debian 6,hadoop 版本是1.0.4,jre 是源里的 openjdk-6。hadoop 官网的说明挺详细,就是不能快速搭建出一个能跑的环境。在网上找到一篇文章(见参考资料 [1]),虽然文章中用的是 0.20 版本,但是在 1.0.4 上也适用。

这里使用 master,slave1 和 slave2 分别作为三台机器的主机名。为了操作方便,每台机器上都有一个用户 hadoop,密码都一样。以下的配置操作都在 master 上进行。

hadoop 的配置(2013.03.16 更新)

把下载到的 hadoop-1.0.4.tar.gz 解压到 hadoop 的家目录下,建立一个软链接 hadoop 指向解压得到的目录,这样以后更新只需重新建立软链接指向新版本即可。

进入解压后的目录,根据实际情况修改 conf/hadoop-env.sh 中的 JAVA_HOME,使其指向 jdk 的安装目录:…

阅读全文…