How to initialize a static variable in a multi-threaded context?

I came up with a good use of the static keyword inside a function to be something like this:

void threadSafeWrite(int *array, int writeIndex, int writeData){
    static void *threadLock = Lock_create(); //in my code locks are void* to be cross-platform compatable
    Lock_aquire(threadLock);
    array[writeIndex] = writeData;
    Lock_release(threadLock);
}

In short, this is a good way to make a critical section. My question is how to initialize threadLock in streaming mode? The problem with the example, I'm afraid, is that the lock will be allocated multiple times, and each thread will use a different lock. Any ideas how to fix this? Looks like a chicken and egg problem. I want a solution (or solutions) that works with both pthreads threads and windows.

EDIT: The reason I want this functionality is because it provides a non-intrusive way to check if there is a difference when running part of the code single-threaded or multi-threaded (intended for debugging).

+3
source share
4 answers

One approach is to use global locking to serialize initialization paths. However, you will need a portable shell on top of the SMP memory; the acquisition barrier implied by locking is insufficient, because it, in principle, allows the compiler and / or CPU to cache memory reads from the moment a lock is detected. Here is an example:

Lock global_init_lock; // Should have low contention, as it only used during startup

void somefunc() {
    static void *data;
    static long init_flag = 0;
    if (!init_flag) { // fast non-atomic compare for the fast path
        global_init_lock.Lock();
        read_memory_barrier(); // make sure we re-read init_flag
        if (!init_flag)
            data = init_data();
        write_memory_barrier(); // make sure data gets committed and is visible to other procs
        init_flag = 1;
        global_init_lock.Unlock();
    }
    read_memory_barrier(); // we've seen init_flag = 1, now make sure data is visible
    // ....
}

, , , . , ? , ? , , ?

+3

, static C. . ++, static main. , :

int deepthought()
{
    return 42;
}

void ask()
{
    static int answer = deepthought();
}

- , MT. - , .

P.S.: void * . struct Lock , .

+3

Lock_create ; , , ! . . , , , C.

, , "", . , . Lock_create .

+2

:

  • (, , ).
  • pthread_once() , , , .
  • , - . , pthreads

    static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
    
0

Source: https://habr.com/ru/post/1787121/


All Articles