【问题标题】:C: How to make this function thread-safe?C: 如何使这个函数线程安全?
【发布时间】:2016-05-15 04:16:29
【问题描述】:

通常当我想让函数线程安全时,我会锁定共享数据,然后在完成工作后释放。

这里我正在使用一个全局变量。简单地锁定和解锁并不能确保函数返回唯一值。如何将以下函数修改为线程安全并确保它始终返回唯一整数?

int count = 0;
int GetUnique()
  {
    count = count + 1;
    return count;
  }

有人提到在函数内部创建一个局部静态变量?这将如何以及为什么会起作用(如果为真)?

【问题讨论】:

  • 函数不需要返回countint local_count; lock(); count = count + 1; local_count = count; unlock(); return local_count;?
  • @iharob - 锁定/解锁是多余的,CPU 有专门的指令来处理这个确切的用例,根本没有任何锁定。
  • @Geoffrey 我假设这是必需的,因为它看起来像家庭作业或类似的东西。
  • @Geoffrey:要以便携的方式执行此操作,无法锁定和解锁。
  • @iharob:为什么不把这个作为答案呢?

标签: c multithreading thread-safety locking


【解决方案1】:

在这种情况下,您希望使用原子增量,如果您使用 GCC 内在函数,则不需要锁定或互斥锁。 __sync_add_and_fetch 是您在这里寻找的,或者对于 VC,InterlockedIncrement 将执行相同的操作。

您可以通过以下方式使此代码可移植:

#ifdef _WIN32
#define SYNC_ADD_AND_FETCH(x) InterlockedIncrement(&(x))
#else
#define SYNC_ADD_AND_FETCH(x) __sync_add_and_fetch(&(x), 1)
#endif

int main(int argc, char *argv[])
{
  int v = 0;
  SYNC_ADD_AND_FETCH(v);
  printf("%d\n", v);
}

将其设为静态不足以保护该变量免受其他线程动态修改它的影响,事实上它没有任何帮助。

【讨论】:

  • 不够”? static 一点帮助都没有。
  • ^^^ @alk 所说的。多线程应用程序库中的“静态”/通常是完全灾难性的。
  • @Marin James - 如果没有观察到原子操作,那只会是灾难性的。
猜你喜欢
  • 2019-03-29
  • 2015-11-30
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多