12.30.2008

Thread safe singleton pattern with C#: easy!

Read Here
Here is the classical manner a thread-safe singleton is written in C#:

class MySingleton
{
private static MySingleton instance;
// Lock synchronization object
private static object syncLock = new object();

private MySingleton() {
DoSomething();
}

public static MySingleton Instance
{
get
{
// Support multithreaded applications
// through 'Double checked locking'
// pattern which (once the instance
// exists) avoids locking each
// time the method is invoked
if (instance == null)
{
lock (syncLock)
{
if (instance == null)
instance = new MySingleton();
}
}
return instance;
}
}
}


摘要:以下這個優美的Thread-Safe Singleton實現基礎是.NET對運行期初始化的完整定義。它的優美之處是不需要典型的double-checked locking。

And now, the ".NET" way:

class Singleton
{
// Static members are lazily initialized.
// .NET guarantees thread safety for
// static initialization
private static readonly Singleton instance = new Singleton ();

// Constructor (private)
private Singleton () { }

public static Singleton Instance {
get { return instance; }
}
}

This works because "private static readonly" involves:

  • lazy initialization
  • thread safety guaranteed by .NET for static initializations.

    Ain't it beautiful?
  • 12.29.2008

    .vimrc

    我的.vimrc

    syntax on
    set tabstop=4
    set softtabstop=4
    set shiftwidth=4
    set backspace=indent,eol,start
    set ic
    set fileencodings=utf-8,gbk,big5,latin1
    set encoding=utf-8
    set fileencoding=utf-8
    set =^U
    set =^B
    set =^G
    map :set fileencoding=utf-8
    map :set fileencoding=big5
    map :set fileencoding=gbk

    除錯程式: gdb

    轉自 洪朝貴教授的gdb教學

    除錯程式: gdb
     
    #include
    #include

    int select_min_index(double data[], int N);
    void swap(double x, double y);

    int main(int argc, char *argv[]) {
    int i, min;
    double data[8];

    for (i = 1; i <= argc; ++i) {
    data[i] = atof(argv[i]);
    }
    for (i = 1; i <= argc; ++i) {
    min = select_min_index(&data[i], argc-i);
    swap(data[i], data[min]);
    }
    for (i = 1; i <= argc; ++i) {
    printf(" %f", data[i]);
    }
    printf("\n");
    return 0;
    }

    int select_min_index(double data[], int N) {
    int j, min = 0;
    for (j = 1; j < N; ++j) {
    if (data[j] < data[min])
    min = j;
    }
    return min;
    }

    void swap(double x, double y) {
    double t;
    t = x;
    x = y;
    y = t;
    }

    假設你要對 a.out 除錯, 可以下指令: gdb a.out 進入 gdb 之後有下列常用指令可用:

    基本指令
    quit: 結束
    help: 求助 (可加指令名稱)
    run: 執行程式 (可加餵給程式的命令列參數)
    list: 列印程式本文 (可加列號或函數名稱)
    print: 印出運算式的值
    中斷指令
    break 列號或函數名稱: 設定中斷點
    info break: 看我們已設定了那些中斷點
    disp 運算式: 每次中斷就顯示這個運算式
    info disp: 看我們已設定了那些顯示式
    next: 執行一列程式碼 (可加欲執行的列數)
    step: 執行一列程式碼, 但是如果遇到函數呼叫, 要跳進函數裡去一步一步執行, 不要把整個函數呼叫當做一步來執行.
    cont: 執行下去, 直到下一個中斷點或程式結束為止
    用於運算式 (例如 print 及 disp 的參數) 中的特殊變數:
    $: 前一次的運算式
    $$: 兩次前的運算式
    $7: 第七個運算式
    $$7: 倒數第七個運算式
    與堆疊有關的指令:
    where: 顯示目前副程式層層呼叫的狀況
    up: 往上一層
    down: 往下一層
    其他指令:
    [CR]: 重複上一個動作
    事實上大部分的指令只要沒有混淆之虞, 都不必完整地打完, 例如 info break 可以簡單地打 i b 就好了

    12.16.2008

    CVS服務設定(精簡版)

    架個CVS自己用爽的,安全性就不是太大考量
    最簡單的方式就是使用 pserver
    若 @CVSROOT/CVSROOT/passwd 檔案不存在,或没有對應用戶的情況下會檢查系統用戶。

    相關設定檔:
    1. /etc/services:將系統所提供的服務名稱及其相對應的port列出
    cvspserver 2401/tcp

    2. Inetd Super Server:
    如果是 inetd, 在 /etc/inetd.conf 中允許原始的端口(2401),那麼下面的命令就足够了(所有命令在conf 中都是單行):
    2401 stream tcp nowait root /usr/local/bin/cvs
    cvs -f --allow-root=/usr/cvsroot pserver

    RH7以後,改用 xinetd 替代 inetd
    建立 /etc/xinetd.d/cvspserver 的文件,包含下列内容:
     
    service cvspserver
    {
    port = 2401
    socket_type = stream
    protocol = tcp
    wait = no
    user = root
    passenv = PATH
    server = /usr/bin/cvs
    server_args = -f --allow-root=/usr/local/cvsroot pserver
    }


    重新啟動相關網路服務
    inetd
    # /etc/rc.d/init.d/inet restart
    xinetd
    # service xinetd restart 或
    # /etc/rc.d/init.d/xinetd restart

    參考:
    CVS中文手冊-簡
    Linux 基本教學 第十一章 Inetd Super Server