C言語は簡単な単例モードを実現する


単例モードとは、プログラム実行中にこの「オブジェクト」のみが存在する「インスタンス」であり、C言語実装単例モードはstaticグローバル変数を簡単に運用することである.
私たちの学号は教務システムの中でいかなる場所でいかなる操作を行っても、対応する学号のデータベースの内容に影響するだけで、例えばあなたは2台のコンピュータの上で前後してあなたの名前を修正して、以下のようにします:
#include 
#include 
#include 
#include 

typedef struct ID{
    char *name;
    int score;    
} id;

static id * _id = NULL;

id *getInstance(){

    if(_id != NULL)
        return _id;
    else {

        _id = (id*)malloc(sizeof(id));
        assert(_id != NULL);
        return _id;
    }
}
int main(){

    id* i1 = getInstance() ;
    i1->name = "Rong";

    id* i2 = getInstance() ;
    i2->name = "Tao";

    if(i1 == i2)
        fprintf(stdout, " i1 == i2 
"); fprintf(stdout, "i1->name = %s
",i1->name); fprintf(stdout, "i2->name = %s
",i2->name); return 0 ; }

上記のコードには、単一のオブジェクトを作成する方法と、その出力の結果が表示されます.
$ ./a.out 
 i1 == i2 
i1->name = Tao
i2->name = Tao

しかし、上記のコードには一定の危険性があり、2台のパソコンで同時にユーザー名を変更する操作を行うと、異なるスレッド間の待機が発生してデッドロックになる可能性があるため、コードをさらに変更する必要があります.
#include 
#include 
#include 
#include 
#include 

typedef struct ID{
    char *name;
    int score;    
} id;

static id * _id = NULL;
static omp_lock_t lock;

id *getInstance(){

    omp_set_lock(&lock);
    if(_id != NULL) {
        omp_unset_lock(&lock);
        return _id;
    } else {

        _id = (id*)malloc(sizeof(id));
        assert(_id != NULL);
        omp_unset_lock(&lock);
        return _id;
    }
}

int main(){

    omp_set_num_threads(20);

    id * i1, *i2;

    omp_init_lock(&lock);
    #pragma omp parallel
    {
        i1 = getInstance() ;
        i1->name = "Rong";
        i1->score = omp_get_thread_num();
    }
    #pragma omp parallel 
    {
        i2 = getInstance() ;
        i2->name = "Tao";
    }
    omp_destroy_lock(&lock);

    if(i1 == i2)
        fprintf(stdout, " i1 == i2 
"); fprintf(stdout, "i1->name = %s, i1->score = %d
",i1->name, i1->score); fprintf(stdout, "i2->name = %s, i2->score = %d
",i2->name, i2->score); return 0 ; }

コンパイルと実行:
$ gcc main2.c -fopenmp
$ ./a.out 
 i1 == i2 
i1->name = Tao, i1->score = 7
i2->name = Tao, i2->score = 7