【问题标题】:when pass static variable by value cause race condition in c当按值传递静态变量时会导致c中的竞争条件
【发布时间】:2016-02-22 16:39:41
【问题描述】:

按值传递(函数范围)静态变量时是否需要加锁:

假设我有一个函数——“myfunction”可以被至少 2 个线程调用:

int myfunction()
{  
    static int var;

    function2(var);
    return var;
}

void function2(int var)
{
    var++;
}

我猜我们需要一个锁来保护它,或者通过指针传递,并在被调用函数内部锁定。因为转换成汇编代码时,至少要进行2次操作:

move REG (var)

push REG

如果第一个线程调用move,而第二个线程修改了var。而当第一个线程调用 push 时,它会推送错误的值。

当您传递 2 字值(64 位)时,情况会变得更糟,传入的高字节和低字节值将不匹配/损坏。

我认为解决方案是通过指针传递,在“function2”中做互斥锁和解锁或将静态变量分配给局部变量,将局部变量传递给function2,并在赋值前后进行锁定和解锁。

我说的对吗?

【问题讨论】:

  • var in myfunction() 未被function2() 修改。参见 C11 标准草案6.5.2.2 Function calls, Section 4 [...] In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument. 93)A function may change the values of its parameters, but these changes cannot affect the values of the arguments.
  • function2修改一个本地副本myfunctionvar值,然后去掉...
  • 静态变量是uint64_t,funcion2是简化版,还有function3。和 function3 修改这个静态变量。 function2 应该是这样的: if(var > constance){ some ops} else {other opts} 所以传入的 var 的“准确性”非常重要。而如果第一个线程做push之后,第二个线程执行function3,并且修改了static var,那么低字节和高字节就会不匹配(损坏)
  • 也许我把我的案例简化得太多了。静态变量是uint64_t,funcion2是简化版,还有function3。和 function3 修改这个静态变量。 function2 应该是这样的: if(var > constance){ some ops} else {other opts} 所以传入的 var 的“准确性”非常重要。假设第一个线程压入一个字节后,第二个线程执行 function3,并修改静态 var, ,然后第一个线程压入另一个字节。所以第一个线程推送的低字节和高字节会不匹配(损坏)

标签: c multithreading locking mutex static-variables


【解决方案1】:

您当前的情况无关紧要,因为function2 的每个线程都将获得自己的var 副本,并且增量值反映在调用者中。

如果您想以线程安全的方式递增整数类型,请使用来自<stdatomic.h> 的适当类型 (ATOMIC_VAR_INIT?) 和函数 (atomic_fetch_add?)。编写自己的函数来执行此操作毫无意义。

【讨论】:

  • 可能是我过于简化了我的案例。静态变量是uint64_t,funcion2是简化版,还有function3。和 function3 修改这个静态变量。 function2 应该是这样的: if(var > constance){ some ops} else {other opts} 所以传入的 var 的“准确性”非常重要。假设第一个线程压入一个字节后,第二个线程执行 function3,并修改静态 var, ,然后第一个线程压入另一个字节。所以第一个线程推送的低字节和高字节会不匹配(损坏)
  • 在这种情况下,我建议您使用 C11 原子库。不要试图自己做这些事情。使用互斥调用会慢一个数量级。
猜你喜欢
  • 1970-01-01
  • 2017-07-13
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
相关资源
最近更新 更多