首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用do_futex搞砸了?

用do_futex搞砸了?
EN

Stack Overflow用户
提问于 2010-08-31 17:16:39
回答 1查看 749关注 0票数 2

我犯了个奇怪的错误。我履行了这两项职能:

代码语言:javascript
复制
int flag_and_sleep(volatile unsigned int *flag)
{
    int res = 0;

    (*flag) = 1;

    res = syscall(__NR_futex, flag, FUTEX_WAIT, 1, NULL, NULL, 0);
    if(0 == res && (0 != (*flag)))
        die("0 == res && (0 != (*flag))");
    return 0;
}

int wake_up_if_any(volatile unsigned int *flag)
{
    if(1 == (*flag))
    {
        (*flag) = 0;
        return syscall(__NR_futex, flag, FUTEX_WAKE, 1, NULL, NULL, 0);
    }
    return 0;
}

并通过运行两个Posix线程来测试它们:

代码语言:javascript
复制
static void die(const char *msg)
{
    fprintf(stderr, "%s %u %lu %lu\n", msg, thread1_waits, thread1_count, thread2_count);
    _exit( 1 );
}

volatile unsigned int thread1_waits = 0;

void* threadf1(void *p)
{
    int res = 0;
    while( 1 )
    {
        res = flag_and_sleep( &thread1_waits );
        thread1_count++;
    }
    return NULL;
}

void* threadf2(void *p)
{
    int res = 0;
    while( 1 )
    {
        res = wake_up_if_any( &thread1_waits );
        thread2_count++;
    }

    return NULL;
}

在thread2进行了大约100万次迭代之后,我得到了assert:

./a.out 0 == res && (0 != (*标志))1 261129 1094433

这意味着syscall --从而返回do_futex() --返回0。男子说,只有在被do_futex(叫醒电话)叫醒时,才能做到这一点。但是在我做叫醒之前,我把旗子设置为0。在这里,旗子仍然是1。

这是英特尔,这意味着强大的记忆模型。因此,如果在thread1中我看到thread2中的syscall的结果,我还必须看到线程2中写入的结果,即调用之前的结果。

旗标和指向它的所有指针都是不稳定的,所以我不认为gcc不能读取正确的值。

我很困惑。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-12-03 15:53:14

当线程1进入整个循环,当线程2从

代码语言:javascript
复制
(*flag) = 0;

代码语言:javascript
复制
return syscall(__NR_futex, flag, FUTEX_WAKE, 1, NULL, NULL, 0);

所以测试是错误的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3611489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档