【问题标题】:pthread scheduling with mutex and condition使用互斥锁和条件进行 pthread 调度
【发布时间】:2013-12-15 21:36:12
【问题描述】:

有人能解释一下为什么在发出条件信号后可以锁定主线程的互斥锁吗?

pthread_t t, v;
pthread_mutex_t m;
pthread_cond_t c;
int res=0;
void* f(void*)
{
    pthread_mutex_lock(&m);
    printf("f-locked\n");
    pthread_cond_wait(&c,&m);
    res=1;
    printf("action!\n");
    pthread_mutex_unlock(&m);
    pthread_exit(NULL);
}
void* mainthread(void*)
{
    setbuf(stdout,NULL);
    struct sched_param sp1;
    sp1.sched_priority=0;
    pthread_mutex_init(&m,NULL);
    pthread_cond_init(&c,NULL);
    pthread_setschedparam(t,SCHED_MIN,&sp1);
    pthread_create(&t,NULL,f,NULL);
    for(int i=0;i<10000000;++i);
    pthread_mutex_lock(&m);
    pthread_cond_signal(&c);
    pthread_mutex_unlock(&m);

    //Why can I lock the mutex again immediately???
    pthread_mutex_lock(&m);
    printf("wtf?\n");
    res=2;
    pthread_mutex_unlock(&m);
    pthread_join(t,NULL);
    printf("\n\nres: %d\n",res);
    pthread_exit(NULL);
}
int main(int argc, char** argv)
{
    struct sched_param sp0;
    sp0.sched_priority=1;
    pthread_setschedparam(v,SCHED_MIN,&sp0);
    pthread_create(&v,NULL,mainthread,NULL);
    pthread_join(v,NULL);
    return 0;
}

结果将是

f-locked
wtf?
action!
res: 1

我相信在主线程发出条件信号并释放互斥锁后,f 函数会立即锁定互斥锁,但它的行为不同。

提前致谢!

【问题讨论】:

  • f 在调用 pthread_mutex_unlock 时在函数结束时解锁。它由主线程发出信号,完成,然后主线程可以获得锁。
  • 在这种情况下,结果将如下:f-locked action!什么? res=2
  • 什么是平台,SCHED_MIN 的记录行为是什么? (这不是我系统上定义的策略,以供比较。)
  • 根据 sched.h,SCHED_MIN 与 SCHED_OTHER 相等

标签: c++ pthreads mutex conditional-statements


【解决方案1】:

抱歉,我第一次没有正确阅读。你所拥有的是一个竞争条件。 pthread_cond_wait 释放互斥锁,并在收到信号时再次锁定互斥锁。我认为this answer explains it pretty well.

无法保证第三个线程会看到来自 两个都。 pthread_cond_signal 会唤醒第三个线程,但它可能不会 立即使用互斥锁。

不保证 f 会在主线程之前获得锁。

【讨论】:

  • 我认为 OP 知道这一点——这就是他明确设置线程调度优先级的原因。
  • 没错。如果我理解正确,我必须制定一些调度逻辑,以保证在发出条件信号后,互斥锁将由等待线程(f)拥有。
【解决方案2】:

我认为这是因为您没有正确使用 pthread_mutex_unlock()。 给你看

printf("action!\n");
pthread_mutex_unlock(&m);
pthread_exit(NULL);

在退出此子线程之前解锁互斥锁。当程序执行 pthread_mutec_unlock() 时,它会首先查找是否有某个线程被锁定。

所以如果你这样写,执行完这条指令后,程序的控制权会立即回到阻塞的主线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2011-09-22
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多