jameszhao00
jameszhao00

Reputation: 7301

C global static - shared among threads?

In C, declaring a variable static in the global scope makes it a global variable. Is this global variable shared among threads or is it allocated per thread?

Update: If they are shared among threads, what is an easy way to make globals in a preexisting library unique to a thread/non-shared?

Update2: Basically, I need to use a preexisting C library with globals in a thread-safe manner.

Upvotes: 8

Views: 24208

Answers (3)

paxdiablo
paxdiablo

Reputation: 882058

It's visible to the entire process, i.e., all threads. Of course, this is in practice. In theory, you couldn't say because threads have nothing to do with the C standard (at least up to c99, which is the standard that was in force when this question was asked).

But all thread libraries I've ever used would have globals accessible to all threads.


Update 1:

Many thread libraries (pthreads, for one) will allow you to create thread-specific data, a means for functions to create and use data specific to the thread without having it passed down through the function.

So, for example, a function to return pseudo random numbers may want each thread to have an independent seed. So each time it's called it either creates or attaches to a thread-specific block holding that seed (using some sort of key).

This allows the functions to maintain the same signature as the non-threaded ones (important if they're ISO C functions for example) since the other solution involves adding a thread-specific pointer to the function call itself.

Another possibility is to have an array of globals of which each thread gets one, such as:

int fDone[10];
int idx;
: : :
for (i = 0; i < 10; i++) {
    idx = i;
    startThread (function, i);
    while (idx >= 0)
        yield();
}

void function () {
    int myIdx = idx;
    idx = -1;
    while (1) {
        : : :
    }
}

This would allow the thread function to be told which global variable in the array belongs to it.

There are other methods, no doubt, but short of knowing your target environment, there's not much point in discussing them.


Update 2:

The easiest way to use a non-thread-safe library in a threaded environment is to provide wrapper calls with mutex protection.

For example, say your library has a non-thread-safe doThis() function. What you do is provide a wrapper for it:

void myDoThis (a, b) {
    static mutex_t serialize;
    mutex_claim (&serialize);
    doThis (a, b);
    mutex_release (&serialize);
}

What will happen there is that only one thread at a time will be able to claim the mutex (and hence call the non-thread-safe function). Others will be blocked until the current one returns.

Upvotes: 20

Franci Penov
Franci Penov

Reputation: 76001

As @Pax mentioned, static variables are visible to all threads. There's no C++ data construct associated with a particular thread.

However, on Windows you can use the TlsAlloc API to allocate index for a thread-specific data and put that index in a static variable. Each thread has its own slot which you can access using this index and the TlsGetValue and TlsSetValue. For more information, read about Using Thread Local Storage on MSDN.

Update: There's no way to make globals in a preexisting library be thread-specific. Any solutions would require you to modify the code as well to be aware that the data has thread affinity.

Upvotes: 1

Kirill V. Lyadvinsky
Kirill V. Lyadvinsky

Reputation: 99635

C/C++ standard doesn't support threads. So all variables shared among threads. Thread support implemented in C/C++ runtime library which is not part of the standard. Runtime is specific for each implementation of C/C++. If you want to write portable code in C++ you could use boost interprocess library.

To declare thread local variable in Microsoft Visual Studio you could use Microsoft specific keyword __declspec( thread ).

Upvotes: 1

Related Questions