C语言hash库 - uthash

uthash 是一个小而强大的C语言的开源hash库,其所有实现均包含在一个头文件-uthash.h中,可以很方便地嵌入C项目中。

uthash的接口都是用宏进行封装,支持任意类型的key,比如int, char[], char*, struct, ptr等等。 支持对item进行add/replace, find, delete, sort, iter, count, select等操作。

简单示例:

#include "uthash.h"
#include <stdio.h>
#include <stdlib.h>

typedef struct user_s {
    int id;
    char *name;
    UT_hash_handle hh;
} user_t;

user_t *users = NULL;

void add_user(int uid, char *name)
{
    user_t *s = (user_t *)malloc(sizeof(user_t));
    s->id = uid;
    s->name = name;
    HASH_ADD_INT(users, id, s);
}

void print_all()
{
    user_t *s;
    for (s=users; s!=NULL; s=(user_t *)(s->hh.next)) {
        printf("id=%d, name=%s\n", s->id, s->name);
    }
}

int id_cmp(user_t *s1, user_t *s2)
{
    return s1->id - s2->id;
}

int main(int argc, char *argv[])
{
    add_user(1, "wang");
    add_user(3, "li");
    add_user(2, "huang");

    user_t *s;
    int uid = 1;
    HASH_FIND_INT(users, &uid, s);
    HASH_DEL(users, s);
    HASH_SORT(users, id_cmp);
    print_all();

    return 0;
}

uthash出现较早,接口简洁强大,使用方便,已经被业界广泛使用。

性能

根据attractivechaos的测试, uthash并不是性能最好的,性能更好的还有khash 等。

Python并发编程

  1. threading,多线程基础库,由于python有GIL的限制故多线程不如其他一些语言强大(无法利用多核),但是在IO密集的情况下使用也可以很好地提高程序的效率。
  2. multiprocessing,多进程基础库,与多线程类似,但是它有一个很大的优点就是可以利用多核,缺点是进程创建开销较大,这一点在不同平台有稍许差异(windows要更大一些?),另外进程间通讯比多线程复杂一些。
  3. queue, multiprocessing.queue,配合前二者进行并发编程,有三种模式: Queue普通先进先出,LifoQueue先进后出,PriorityQueue优先级
  4. select/poll/epoll

To be continued...

Python的import机制

在C语言中头文件一般是不能重复include的,否则会出现重定义错误。因此一般会在头文件中加上类似以下的判断:

#pragma once
#ifndef __XXXX_H
#define __XXXX_H
#endif

#pragma once与#ifndef...#define...#endif作用相同,但前者更快。前者是平台相关的,移植性较差,后者为语言特性,可移植性好,实际可混合使用。

python中也采用了一定的处理规则来防止重复import。

简单来说, import的过程中做了下面几件事:

  1. 在sys.modules查找该模块,如果存在,则返回。
  2. 在sys.path包含的路径中查找该模块
  3. 如果找到该模块,则将模块信息加入sys.modules, sys.modules为保存当前加载模块信息的一个dict, 对应格式为{'xxxx': <module 'xxxx' from '/usr/lib/.../xxxx.py'>}, 执行该模块文件,如未出错,将模块(import XXXX)或者其中的变量(from XXXX import *)加入globals()和locals()。

现在我们有两个循环调用的python模块:a.py和b.py,各自都import了对方,现在我们python a.py,则其执行过程如下:

  1. a中import b:sys.modules无b,故查找b模块,添加至sys.modules, 执行
  2. 执行b模块,b中import a,sys.modules无a, 故查找a,添加至sys.modules, 执行
  3. 执行a模块,import b时sys.modules中已有故直接跳过,返回至2(4)
  4. 返回到2后执行b完成返回到1(5)
  5. 返回到1后继续执行a其他代码

用图表示为:

/attachment/import_1_e380c13ac16479fd38b696b13f72b8da.png
MORE