【发布时间】:2014-10-15 04:06:39
【问题描述】:
我在 Ubuntu (json-c/json.h) 下使用 C JSON 库。我需要在多个 POSIX 线程上解析 JSON 字符串。目前正在使用 json_tokener_parse() 方法 - 这个多线程安全还是我需要使用其他方法?
thnx
【问题讨论】:
标签: c json multithreading json-c
我在 Ubuntu (json-c/json.h) 下使用 C JSON 库。我需要在多个 POSIX 线程上解析 JSON 字符串。目前正在使用 json_tokener_parse() 方法 - 这个多线程安全还是我需要使用其他方法?
thnx
【问题讨论】:
标签: c json multithreading json-c
我查看了代码: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() 的调用不会产生实际影响。
【讨论】:
setlocale(LC_ALL, "C") 的功能吗?
newlocale 和 uselocale 来解决,但事实上 LC_NUMERIC 可能会弄乱浮点解析和打印的小数点,这是一个很难解决的大问题以线程安全、可移植和高效的方式解决问题。
"C" 保证是启动时的语言环境。我会更新我的答案以反映这一点。
setlocale 时默认情况下“C”语言环境处于活动状态这一事实是如何相关的。对setlocale 的调用仍然是个问题。
strtod 从头开始重新实现非常重要,这就是它使用特定于语言环境的基数字符如此糟糕的全部原因。但是,您可以通过localeconv 函数获取该字符,因此您可以在调用strtod 之前“重新格式化”字符串以使用区域设置的基数字符。