【问题标题】:Thread synchronization in Linux?Linux中的线程同步?
【发布时间】:2018-09-16 01:52:06
【问题描述】:

我正在编写一个代码,其中我让我的线程等到我执行 pthread_cond_broadcast。我在这段代码中有三个线程。线程 line2_thread 和 line3_thread,按照它们应该运行的优先级顺序运行。然而,我的第三个线程甚至没有进入它的线程函数(line4_thread)。谁能告诉我为什么我的 main() 不能调用我的 line4_thread ? pthread_cond_t 开始; pthread_mutex_t sstart_mutex;

void *l3_thread(void *arg){

pthread_mutex_lock(&sstart_mutex);
pthread_cond_wait(&sstart, &sstart_mutex);
pthread_mutex_unlock(&sstart_mutex);
/*do something*/

pthread_exit(NULL);

}

void *l2_thread(void *arg){

pthread_mutex_lock(&sstart_mutex);
pthread_cond_wait(&sstart, &sstart_mutex);
pthread_mutex_unlock(&sstart_mutex);
/*do something*/

pthread_exit(NULL);

}


void *l4_thread(void *arg){

pthread_mutex_lock(&sstart_mutex);
pthread_cond_wait(&sstart, &sstart_mutex);
pthread_mutex_unlock(&sstart_mutex);
/*do something*/

pthread_exit(NULL);

}

int main(){

pthread_cond_init(&sstart, NULL);

//thread creation

pthread_cond_broadcast(&sstart);
pthread_cond_destroy(&sstart);
    pthread_mutex_destroy(&sstart_mutex);

return 0;
}

【问题讨论】:

  • 你能显示 attr_for_line4 声明以及它是如何设置的吗?
  • 另外,你的加入...是否有可能 main 在 line4 有机会运行之前退出?
  • pthread_t line4; pthread_attr_t attr_for_line4; int prio_line4 = 30;结构 sched_pa​​ram p_line4; pthread_attr_init (&attr_for_line4); temp_line4 = pthread_attr_getschedparam (&attr_for_line4, &p_line4); p_line4.sched_priority = prio_line4; pthread_attr_setschedparam (&attr_for_line4, &p_line4); pthread_attr_setschedpolicy(&attr_for_line4, SCHED_FIFO);
  • 即使我在其他两个之前调用line4_thread,它也不会只进入函数。
  • 可能是因为您遇到了死锁。 this question 包含更多信息

标签: c multithreading pthreads mutex thread-synchronization


【解决方案1】:

我认为您在这里遇到了一些问题。抱歉(我在手机上,所以很难输入一个长答案)我只想专注于几件事,因为我并不是 100% 清楚你实际上想要做什么。

当您的所有线程启动时,它们都尝试获取互斥锁,但只有一个成功。可能是l3,但我认为这里不能保证。然后它调用pthread_cond_wait 并解锁互斥锁,允许其他线程之一到达它的pthread_cond_wait。但与此同时。您已经允许您的主线程调用pthread_cond_broadcast,并且您没有采取任何步骤将其与其他线程同步。这可能发生在其他人等待互斥锁被解除阻塞之前,以及在他们的wait 调用之前,因此他们可能会错过信号并永远阻塞。

此外,我认为立即致电pthread_cond_destroy 有点粗略。就像我说的,你的主线程和你的工作线程之间没有同步,所以你可以调用pthread_cond_broadcast,然后调用pthread_cond_destroy,所以你的一些线程可能会在无效的条件变量和死锁上调用pthread_cond_wait

检查pthread_cond_wait 的返回值。如果我是对的,在某些情况下它可能会返回 EINVAL。但是我没有对此进行测试,因此我的推理可能存在缺陷。

【讨论】:

  • 好答案...在其他人仍在使用条件变量时销毁条件变量可能会导致未定义的行为。我不会假设它可能会死锁或返回EINVAL
  • 这是解释性的。我尝试在 10 秒后破坏条件等待。我希望我的代码运行 10 秒,并希望它们按优先级顺序执行。 10 秒后,两个线程完成执行,我仍然没有看到 l4 线程正在执行(最低优先级)。
  • 在线程完全完成运行之前(例如,在所有连接调用之后)销毁条件是没有意义的。同时,你还有其他问题。就像我写的那样,您的主线程和工作线程之间没有同步,因此例如,您没有以可以保证pthread_cond_broadcast 将同时到达所有线程的方式设计东西——也就是说,他们都在你广播时等待的条件下被阻止。
  • 当我进行 cond 广播时,l2 线程释放静音,然后 l3 保持直到它释放它。由于 l3 也在运行,这是否意味着它已经释放了互斥体供 l4 获取?因为 l2 和 l3 的 /*do something*/ 正在完成。我对这条路感到非常困惑?
  • 此外,我想我可以解决这个问题,但是我在上面的评论中对代码流程的理解是否正确?
猜你喜欢
  • 1970-01-01
  • 2019-09-28
  • 2020-07-29
  • 2023-03-13
  • 1970-01-01
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
相关资源
最近更新 更多