C++程序  |  77行  |  1.71 KB

/* This program is used to test that one-time-construction
 * works correctly, even in the presence of several threads.
 */

#include <new>
#include <pthread.h>
#include <stdio.h>

#define MAX_THREADS 100

class Foo {
public:
    Foo() { mValue++; }
    int getValue() { return mValue; }
private:
    static int  mValue;
};

int Foo::mValue;

static Foo*  getInstance(void)
{
    // This construct forces the static creation of _instance
    // the first time that getInstance() is called, in a thread-safe
    // way.
    static Foo  _instance;
    return &_instance;
}

static Foo*       sInstances[MAX_THREADS];
static pthread_t  sThreads[MAX_THREADS];

static void* thread_run(void* arg)
{
    int index = (int)(intptr_t)arg;
    sInstances[index] = getInstance();
    return NULL;
}

int main(void)
{
    /* Create all the threads */
    for (int nn = 0; nn < MAX_THREADS; nn++) {
        pthread_create( &sThreads[nn], NULL, thread_run, reinterpret_cast<void*>(nn) );
    }
    /* Wait for their completion */
    for (int nn = 0; nn < MAX_THREADS; nn++) {
        void* dummy;
        pthread_join( sThreads[nn], &dummy );
    }
    /* Get the instance */
    Foo*  foo = getInstance();

    if (foo == NULL) {
        fprintf(stderr, "ERROR: Foo instance is NULL!\n");
        return 1;
    }

    if (foo->getValue() != 1) {
        fprintf(stderr, "ERROR: Foo constructor called %d times (1 expected)\n",
                foo->getValue());
        return 2;
    }

    int count = 0;
    for (int nn = 0; nn < MAX_THREADS; nn++) {
        if (sInstances[nn] != foo)
            count++;
    }

    if (count != 0) {
        fprintf(stderr, "ERROR: There are %d invalid instance pointers!\n", count);
        return 3;
    }
    return 0;
}