C 全局静态 - 在线程之间共享?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1338846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C global static - shared among threads?
提问by jameszhao00
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?
在 C 中,在全局范围内声明一个 static 变量使其成为全局变量。这个全局变量是在线程之间共享的还是每个线程分配的?
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.
更新 2:基本上,我需要以线程安全的方式使用预先存在的带有全局变量的 C 库。
回答by paxdiablo
It's visible to the entire process, i.e., allthreads. 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)将允许您创建特定于线程的数据,这是函数创建和使用特定于线程的数据而无需通过函数传递数据的一种方式。
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 easiestway 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:
例如,假设您的库具有非线程安全doThis()
功能。你要做的是为它提供一个包装器:
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.
将会发生的情况是一次只有一个线程能够声明互斥锁(从而调用非线程安全函数)。其他人将被阻止,直到当前一个返回。
回答by Kirill V. Lyadvinsky
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.
C/C++ 标准不支持线程。所以所有变量在线程之间共享。在 C/C++ 运行时库中实现的线程支持不是标准的一部分。运行时特定于 C/C++ 的每个实现。如果你想用 C++ 编写可移植的代码,你可以使用boost interprocess library。
To declare thread local variable in Microsoft Visual Studio you could use Microsoft specific keyword __declspec( thread )
.
要在 Microsoft Visual Studio 中声明线程局部变量,您可以使用 Microsoft 特定关键字__declspec( thread )
.
回答by Franci Penov
As @Pax mentioned, static variables are visible to all threads. There's no C++ data construct associated with a particular thread.
正如@Pax 提到的,静态变量对所有线程都是可见的。没有与特定线程相关联的 C++ 数据构造。
However, on Windows you can use the TlsAllocAPI 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 Storageon MSDN.
但是,在 Windows 上,您可以使用TlsAllocAPI 为特定于线程的数据分配索引并将该索引放入静态变量中。每个线程都有自己的插槽,您可以使用此索引以及 TlsGetValue 和 TlsSetValue 访问该插槽。有关更多信息,请阅读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.
更新:无法使预先存在的库中的全局变量成为线程特定的。任何解决方案都需要您修改代码以了解数据具有线程关联性。