静态变量和线程(C)

dah*_*hui 13 c concurrency static multithreading mutual-exclusion

我知道在C中的函数中声明一个静态变量意味着该变量在函数调用之间保留其状态.在线程的上下文中,这会导致变量在多个线程上保持其状态,还是在每个线程之间具有单独的状态?

以下是我正在努力回答的过去的纸质考试问题:

以下C函数旨在用于为其调用者分配唯一标识符(UID):

get_uid() 
{
static int i = 0;
return i++;
}
Run Code Online (Sandbox Code Playgroud)

解释get_uid()在多线程调用它的环境中可能会以何种方式正常工作.使用特定示例方案,详细说明可能发生此类错误行为的原因和方式.

目前我假设每个线程都有一个单独的变量状态,但我不确定这是否正确,或者答案是否与缺少互斥有关.如果是这种情况,那么在这个例子中如何实现信号量呢?

P.P*_*.P. 18

你的假设(线程有自己的副本)是不正确的.代码的主要问题是当多个线程调用该函数时get_uid(),可能存在 竞争条件,即哪些线程递增i并获取可能不唯一的ID.


Jim*_*ter 9

进程的所有线程共享相同的地址空间.由于i是静态变量,因此它具有固定地址.它的"状态"只是该地址的内存内容,由所有线程共享.

后缀++运算符递增其参数并在递增之前产生参数的值.没有定义完成这些操作的顺序.一种可能的实现是

copy i to R1
copy R1 to R2
increment R2
copy R2 to i
return R1
Run Code Online (Sandbox Code Playgroud)

如果正在运行多个线程,则它们可以同时执行这些指令或散布.找出各种结果的序列.(请注意,每个线程都有自己的寄存器状态,即使对于在同一CPU上运行的线程也是如此,因为在切换线程时会保存并恢复寄存器.)

这样的情况,根据不同线程中的操作的不确定性排序,存在不同的结果被称为竞争条件,因为在不同的线程中存在关于哪个操作首先执行哪个操作的"竞争".


Ste*_*and 5

不,如果您想要一个其值取决于使用它的线程的变量,您应该看看线程本地存储。

静态变量,你可以想象它真的像一个完全的全局变量。真的很相似。因此它由知道其地址的整个系统共享。

编辑:同样作为注释提醒它,如果您将此实现保留为静态变量,竞争条件可能会使该值i同时由多个线程递增,这意味着您不知道该值将由函数调用返回。在这种情况下,您应该通过所谓的同步对象(如互斥体临界区)来保护访问。