Saturday, April 13, 2013

[C] 线程局部存储 (thread-local storage)

GCC 支持使用线程局部存储(TLS)来方便多线程的编程.通俗来说, TLS就是一些看起来global的变量, 但是它实际上是per-thread的
使用TLS很简单,只需要用__thread关键字来修饰一个"全局变量",比如下面例子里的tid. 它在不同的thread里被输出的时候就是输出不同的值
#include <stdio.h>
#include <pthread.h<
#define NUM_THREADS     5

__thread long tid;

void print_tid() {
    printf("Hello World! It's me, thread #%ld!\n", tid);
}

void *run_thread(void *threadid)
{
    tid = (long)threadid;
    print_tid();
    pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
    pthread_t threads[NUM_THREADS];
    int rc;
    long t;
    for(t=0; t<NUM_THREADS; t++){
        rc = pthread_create(&threads[t], NULL, run_thread, (void *)t);
        if (rc){
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            exit(-1);
        }
    }

    /* Last thing that main() should do */
    pthread_exit(NULL);
}
运行
$ gcc test_tls.c
$ ./a.out 
Hello World! It's me, thread #0!
Hello World! It's me, thread #1!
Hello World! It's me, thread #2!
Hello World! It's me, thread #3!
Hello World! It's me, thread #4!

参考

GCC对TLS的支持

Thursday, April 11, 2013

[C/C++] 随机数

C里的RAND


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

int main()    
{    
    srand(time(0));   
    printf("%d\n", rand());    
    return 0;    
}

使用C++11 里的Mersenne Twister随机数


C++11支持的Mersenne Twister可以非常轻量级的快速生成大量随机数.适合在benchmark的时候使用
#include <iostream>
#include <random>
main() {    
    std::mt19937_64 rng;
    // 使用系统时间生成随机数种子
    rng.seed(static_cast<unsigned int>(std::time(0)));

    // 生成32-bit的随机整数
    std::cout << rng() << std::endl;

    // 生成 1到255之间(包括1和255) 的随机数
    std::uniform_int_distribution<int> unif(1, 255);
    std::cout << unif(rng)<< std::endl;

    // 以概率0.3生成true, 0.7生成false
    std::bernoulli_distribution bern(0.3);
    std::cout << bern(rng) << std::endl;

}