sscanf 在 iPhone OS 3.1.2 上是线程安全的吗?

发布于 2024-08-15 14:44:12 字数 1513 浏览 5 评论 0原文

当我最终意识到问题是从多个线程调用 sscanf 时,我只是花了一整天的时间调试一个随机错误。

我通过运行以下代码进行确认,该代码在 Snow Leopard 上按预期工作,但在操作系统 3.1.2 的 iphone 上产生非常奇怪的结果。它在模拟器中也运行良好。

在 iPhone 上,解析的数字将是字符串中使用的数字的随机组合。

如果有人可以检查这是否是一个普遍问题或者是否是我这边的错误,那将非常有帮助。

- (void)testIt
 {
    [NSThread detachNewThreadSelector:@selector(scanfTest) toTarget:self withObject:nil];
    [NSThread detachNewThreadSelector:@selector(scanfTest) toTarget:self withObject:nil];
}

- (void)scanfTest
{
    while (true)
    {
      float value = 0.0f;
      sscanf("456", "%f", &value);
      sscanf( "1.63", "%f", &value);
      if (value != 1.63f)
        NSLog(@"strange value is %f", value);
    }
}

我做了一些进一步的检查,看来只有浮点数才是问题。
此代码有效

- (void)scanfTest4
{
    while (true)
    {
        int year = 0;
        int month = 0;
        int day = 0;
        sscanf("20090131", "%4d%2d%2d", &year, &month, &day);
        sscanf("19840715", "%4d%2d%2d", &year, &month, &day);
        if (year != 1984 || month != 7 || day != 15)
            NSLog(@"bla");
    }
}

,此代码因相同的随机数字问题而失败

- (void)scanfTest4
{
    while (true)
    {
        int year = 0;
        int month = 0;
        float day = 0.0f;
        sscanf("20090131", "%4d%2d%2f", &year, &month, &day);
        sscanf("19840715", "%4d%2d%2f", &year, &month, &day);
        if (year != 1984 || month != 7 || day != 15.0f)
            NSLog(@"bla");
    }
}

I was just spending my whole day debugging a random bug when i finally realized the Problem was sscanf being called from multiple threads.

I confirmed by running the following code which works as expected on Snow Leopard but produces very strange results on my iphone with os 3.1.2. It also works fine in the Simulator.

On the iPhone the parsed number will be a somewhat random combination of the digits used in the strings.

It would be very helpfull if anyone could check if this is a general Problem or if it's a mistake on my side.

- (void)testIt
 {
    [NSThread detachNewThreadSelector:@selector(scanfTest) toTarget:self withObject:nil];
    [NSThread detachNewThreadSelector:@selector(scanfTest) toTarget:self withObject:nil];
}

- (void)scanfTest
{
    while (true)
    {
      float value = 0.0f;
      sscanf("456", "%f", &value);
      sscanf( "1.63", "%f", &value);
      if (value != 1.63f)
        NSLog(@"strange value is %f", value);
    }
}

I did some further checking and it appears only floating point numbers are an issue.
This code works

- (void)scanfTest4
{
    while (true)
    {
        int year = 0;
        int month = 0;
        int day = 0;
        sscanf("20090131", "%4d%2d%2d", &year, &month, &day);
        sscanf("19840715", "%4d%2d%2d", &year, &month, &day);
        if (year != 1984 || month != 7 || day != 15)
            NSLog(@"bla");
    }
}

And this code fails with the same random digit issues

- (void)scanfTest4
{
    while (true)
    {
        int year = 0;
        int month = 0;
        float day = 0.0f;
        sscanf("20090131", "%4d%2d%2f", &year, &month, &day);
        sscanf("19840715", "%4d%2d%2f", &year, &month, &day);
        if (year != 1984 || month != 7 || day != 15.0f)
            NSLog(@"bla");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少女净妖师 2024-08-22 14:44:12

SUSv2 说(线程):

由此定义的所有接口
规范将是线程安全的,
除了以下接口
不必是线程安全的

sscanf() 不在不需要线程安全的接口列表中。

这并不是说 iPhone 符合 SUSv2 标准,但我认为它至少解释了为什么您的代码应该在 Snow Leopard 上运行。另外,我手头没有更新的 POSIX 规范,因此我假设它自 1997 年以来就没有发生过变化,这有点冒险。

SUSv2 says (Threads):

All interfaces defined by this
specification will be thread-safe,
except that the following interfaces
need not be thread-safe

sscanf() is not on the list of interfaces which need not be thread-safe.

This is not to say that the iPhone is SUSv2-compliant, but I think at least it explains why your code should be expected to work on Snow Leopard. Also I don't have a more recent POSIX spec to hand, so I'm taking a bit of a risk in assuming it hasn't changed since 1997.

青芜 2024-08-22 14:44:12

sscanf 不是线程安全的。它是在线程存在之前编写的,其设计要求它使用内部静态临时变量。 sprintf 也是如此。

我的情况是, sscanf 无论如何都太过分了。只需使用 atof 即可。

sscanf is not thread safe PERIOD. it was written before threads existed its design requires it to use internal static temp variables. the same is true for sprintf.

I your case, sscanf is overkill anyway. just use atof instead.

贵在坚持 2024-08-22 14:44:12

谢谢约翰和斯蒂芬!

我可以确认 atof 和 strtof 在这种情况下都可以安全使用。

Thank you John and Stephen!

I can confirm that both atof and strtof are safe to use in this situation.

始于初秋 2024-08-22 14:44:12

如果我可能会问,当您可以使用 NSString 数字转换时,为什么需要使用 sscanf/atof ?

If I may ask, why do you need to use sscanf/atof when you can use the NSString numeric conversions?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文