【问题标题】:Is the JSON C library thread-safe?JSON C 库是线程安全的吗?
【发布时间】:2014-10-15 04:06:39
【问题描述】:

我在 Ubuntu (json-c/json.h) 下使用 C JSON 库。我需要在多个 POSIX 线程上解析 JSON 字符串。目前正在使用 json_tokener_parse() 方法 - 这个多线程安全还是我需要使用其他方法?

thnx

【问题讨论】:

标签: c json multithreading json-c


【解决方案1】:

我查看了代码:https://github.com/json-c/json-c/blob/master/json_tokener.c

它似乎是线程安全的,但有一个例外:

#ifdef HAVE_SETLOCALE
  char *oldlocale=NULL, *tmplocale;

  tmplocale = setlocale(LC_NUMERIC, NULL);
  if (tmplocale) oldlocale = strdup(tmplocale);
  setlocale(LC_NUMERIC, "C");
#endif

因此,如果定义了HAVE_SETLOCALE(可能会),则将调用setlocale(),并将进程范围的LC_NUMERIC 设置为"C"。当然,它最终会撤消这一点。如果您的 LC_NUMERIC 一开始不是 "C" 或兼容的语言环境,这将导致问题,因为一个线程将“恢复”您的语言环境,而另一个线程可能仍在解析并期望 "C" 语言环境有效。

幸运的是,可以保证程序启动时语言环境将是 "C",因此您只需要确保您或您使用的任何其他库都不会设置 LC_NUMERIC(当然是 LC_ALL)与"C" 不兼容的语言环境。然后,您可以根据需要使用 HAVE_SETLOCALE undefined 重建库,但这可能无关紧要,因为它对 setlocale() 的调用不会产生实际影响。

【讨论】:

  • 好收获。 C 库在启动时不做相当于setlocale(LC_ALL, "C") 的功能吗?
  • 这可以通过正确使用 newlocaleuselocale 来解决,但事实上 LC_NUMERIC 可能会弄乱浮点解析和打印的小数点,这是一个很难解决的大问题以线程安全、可移植和高效的方式解决问题。
  • @JonathanLeffler:啊哈,你也很好。你说得对,"C" 保证是启动时的语言环境。我会更新我的答案以反映这一点。
  • @JonathanLeffler:我看不出当您不调用setlocale 时默认情况下“C”语言环境处于活动状态这一事实是如何相关的。对setlocale 的调用仍然是个问题。
  • @JohnZwinck: strtod 从头开始​​重新实现非常重要,这就是它使用特定于语言环境的基数字符如此糟糕的全部原因。但是,您可以通过localeconv 函数获取该字符,因此您可以在调用strtod 之前“重新格式化”字符串以使用区域设置的基数字符。
猜你喜欢
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 2012-08-19
  • 2012-03-23
  • 1970-01-01
  • 2017-06-19
  • 2019-09-20
相关资源
最近更新 更多