我在多线程应用程序中使用localtime。
我必须用线程安全的版本替换它,据我所知,这个版本叫做localtime_r。
然而,当我这样做时,由于链接失败,我无法完成构建。
我甚至不确定从哪里开始寻找解决方案。
我的系统组件是:
我假设(虽然我不确定),这个函数通常会在随IDE提供的标准库中提供。我是对的吗?
我是否需要将另一个库添加到项目中,或者是项目设置中的某个库?
如果没有可行的方法将此函数“导入”我的代码,我还有哪些其他选项可用于本地时间函数的线程安全版本?
更新
我希望避免使用OS资源(即互斥锁),而是调用一个标准例程,该例程完全执行'localtime'所做的事情,只是没有它使用的静态结构(使其不安全)
我没有看到为什么localtime会使用静态结构开始的原因,所以我假设相应的localtime_r并没有用任何操作系统资源来解决它,而只是禁止使用静态结构。
如果没有这样的选择是可行的,那么我不妨自己实施,只是因为约会系统的“不规则”,我更喜欢使用已经过适当测试的东西。
这里的问题是,如何将localtime_r'链接到我的项目中(而不是如何实现localtime_r)。
由于
答案 0 :(得分:5)
您需要为localtime()创建自己的线程安全包装器,它基本上是实现localtime_r()。
e.g。
static TX_MUTEX localtime_lock;
void my_localtime_init(void)
{
tx_Mutex_create( &localtime_lock, "localtime_lock", TX_INHERIT);
}
struct tm *my_localtime_r(const time_t *tim, struct tm *result)
{
struct tm *t;
tx_Mutex_get(&localtime_lock, TX_WAIT_FOREVER);
t = localtime(tim);
if (t)
*result = *t;
tx_Mutex_put(&localtime_lock);
return t ? result : NULL;
}
您需要在启动时的某处调用my_localtime_init
。
这也意味着你需要用my_localtime_r
函数替换所有调用,没有人可以直接调用localtime(),因为这可能导致调用新my_localtime_r的代码出现竞争条件。
答案 1 :(得分:3)
如果没有可用的线程安全版本,则必须创建一个版本,该版本具有localtime_r()
的标准接口,但使用互斥锁来确保互斥。我可能会使用相同的名称,但是有一些参数可以使用您经常调用的替代名称,如果可用,则会直接调用localtime_r
。
如果您的系统使用与Pthread互斥锁不同的互斥锁,则该概念适用;使用本机互斥锁而不是Pthread互斥锁。
static pthread_mutex_t mx_localtime_r = PTHREAD_MUTEX_INITIALIZER;
struct tm *localtime_r(const time_t *restrict timer, struct tm *restrict result)
{
struct tm *r = 0;
if (pthread_mutex_lock(&mx_localtime_r) == 0)
{
r = localtime(timer);
if (r != 0)
{
*result = *r;
r = result;
}
if (pthread_mutex_unlock(&mx_localtime_r) != 0)
r = 0;
}
return r;
}
未编译 - 更少测试。
如果互斥锁的默认属性不适合您,那么您需要投入更多精力来正确初始化互斥锁。