标准 C 函数"localtime"的线程安全版本



我在多线程应用程序中使用localtime。

我必须用线程安全版本替换它,据我了解,它被称为localtime_r。

但是,当我这样做时,由于链接失败,我无法完成构建。

我什至不确定从哪里开始寻找解决方案。

我的系统组件是:

  • 芯片 - STM32(基于ARM的皮层)
  • IDE - IAR(用于ST-微控制器的编译器和链接器)
  • 操作系统 - 线程X

我假设(尽管我不确定),此功能通常会在与 IDE 一起提供的标准库中提供。我说的对吗?

是否有其他库需要添加到我的项目中,或者它是否在项目设置中?

如果没有可行的方法将此函数"导入"到我的代码中,那么对于 localtime 函数的线程安全版本,我还有哪些其他选项?

更新:

我希望避免使用操作系统资源(即互斥锁),而是调用一个标准例程,该例程完全执行"localtime"所做的事情,只是没有它使用的静态结构(使其线程不安全)。

我看不出 localtime 一开始会使用静态结构的任何理由,所以我假设相应的localtime_r不会使用任何操作系统资源来解决它,而只是避免使用静态结构。

如果没有这样的选项是可行的,那么我不妨自己实现它,只是由于约会系统的"不规则性",我更喜欢使用已经过正确测试的东西。

这里的问题是,如何将localtime_r'链接到我的项目中(而不是如何实现localtime_r)。

谢谢

你需要为localtime()创建自己的包装器,它是线程安全的,基本上是实现localtime_r()。

例如

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的代码出现竞争条件。

如果没有可用的线程安全版本,则必须创建一个,它具有用于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;
}

未编译 — 测试更少。

如果互斥锁的默认属性不适合您,则需要投入更多精力来正确初始化互斥锁。

最新更新