简体   繁体   English

C全局静态 - 在线程之间共享?

[英]C global static - shared among threads?

In C, declaring a variable static in the global scope makes it a global variable. 在C中,在全局范围内声明变量static使其成为全局变量。 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. Update2:基本上,我需要以线程安全的方式使用带有全局变量的预先存在的C库。

It's visible to the entire process, ie, 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). 从理论上讲,你不能说因为线程与C标准无关(至少达到c99,这是提出这个问题时生效的标准)。

But all thread libraries I've ever used would have globals accessible to all threads. 但是我用过的所有线程库都会有所有线程都可以访问的全局变量。


Update 1: 更新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. 许多线程库(pthreads,for one)将允许您创建特定于线程的数据,这是一种用于创建和使用特定于线程的数据的函数的方法,而不会通过该函数向下传递。

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. 这允许函数保持与非线程函数相同的签名(例如,如果它们是ISO C函数,则很重要),因为另一个解决方案涉及向函数调用本身添加特定于线程的指针。

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: 更新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. 例如,假设您的库具有非线程安全的doThis()函数。 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. 其他人将被阻止,直到当前的人返回。

C/C++ standard doesn't support threads. C / C ++标准不支持线程。 So all variables shared among threads. 所以线程之间共享所有变量。 Thread support implemented in C/C++ runtime library which is not part of the standard. 在C / C ++运行时库中实现的线程支持,它不是标准的一部分。 Runtime is specific for each implementation of C/C++. 运行时特定于C / C ++的每个实现。 If you want to write portable code in C++ you could use boost interprocess library . 如果您想用C ++编写可移植代码,可以使用boost进程库

To declare thread local variable in Microsoft Visual Studio you could use Microsoft specific keyword __declspec( thread ) . 要在Microsoft Visual Studio中声明线程局部变量,您可以使用Microsoft特定的关键字__declspec( thread )

As @Pax mentioned, static variables are visible to all threads. 正如@Pax所提到的,静态变量对所有线程都是可见的。 There's no C++ data construct associated with a particular thread. 没有与特定线程关联的C ++数据结构。

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. 但是,在Windows上,您可以使用TlsAlloc API为特定于线程的数据分配索引,并将该索引放在静态变量中。 Each thread has its own slot which you can access using this index and the TlsGetValue and TlsSetValue. 每个线程都有自己的插槽,您可以使用此索引以及TlsGetValue和TlsSetValue进行访问。 For more information, read about Using Thread Local Storage on MSDN. 有关更多信息,请阅读有关在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. 任何解决方案都需要您修改代码以了解数据是否具有线程关联性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM