当我终于意识到问题是从多个线程调用 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);
}
}
我做了一些进一步的检查,似乎只有 float 是个问题。
此代码有效
- (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");
}
}
最佳答案
SUSv2 说(Threads):
All interfaces defined by this specification will be thread-safe, except that the following interfaces need not be thread-safe
sscanf()
不在不需要线程安全的接口(interface)列表中。
这并不是说 iPhone 符合 SUSv2,但我认为至少它解释了为什么您的代码应该在 Snow Leopard 上运行。此外,我手头没有更新的 POSIX 规范,所以我假设它自 1997 年以来没有改变,这有点冒险。
关于iphone - sscanf 在 iPhone OS 3.1.2 上是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1943622/