gpt4 book ai didi

c - 多线程同步

转载 作者:行者123 更新时间:2023-11-30 17:48:28 25 4
gpt4 key购买 nike

我正在使用 glibc pthreads 库编写一个多线程应用程序。我有 3 个 pthreads - 其中一个称为“调度程序”,另外两个称为“工作线程”和主线程。主线程监听事件并将它们放入队列中。然后调度程序线程将它们分派(dispatch)到工作队列。工作线程从工作队列中获取事件并执行。问题是有时,事件必须在主线程本身中执行,以防止主要数据争用。因此,我需要一种机制来在收到特殊事件时暂停主线程,并等待所有工作人员完成其工作,然后执行该事件。

为了做到这一点,我使用了一个受互斥体保护的整数,其位由工作线程设置和重置。当worker在其队列中发现没有作业时,它将把它的位设置为0。如果有作业,那么它将把它的位标记为1。这个想法是,如果其中一个worker正在运行,那么整数就是!= 0.现在,当主线程想要暂停自己以便工作人员完成时,现在将进行条件等待,直到整数变为 0。工作线程在重置其位时将检查整数是否变为 0。如果为真,则它将向主线程发出信号。此时,我期望所有工作人员的队列中都没有作业,因此主线程可以执行特殊事件。由于主线程负责将事件排队到第一个队列,因此我们可以保证没有事件会潜入工作人员中。

伪代码如下。

int pause_threads() => the one called from main thread.  
{
pthread_mutex_lock(pause_thread_lock));

while (pthread_states != 0) {
pthread_cond_wait(pause_mthread_cond), pause_thread_lock));
}

}

int thread_resume() => called after the special event is executed by main thread.
{
pthread_mutex_unlock(pause_thread_lock));
}

int thread_set_state_wait(index) => index is id 0,1 for each worker
{
pthread_mutex_lock(pause_thread_lock));
(thread_states) &= (~(MTHREAD_THR_STATE_RUNNING << index));
if (pthread_states == 0)
pthread_cond_signal(pause_thread_cond));
pthread_mutex_unlock(&(pause_thread_lock));
}

int thread_set_state_running(index)
{
pthread_mutex_lock(pause_thread_lock));
(pthread_states) |= (MTHREAD_THR_STATE_RUNNING << index);
pthread_mutex_unlock(pause_thread_lock));

}

我面临的问题是这段代码并不总是有效。有时,我看到当主线程正在执行特殊事件时,工作线程仍然处于事件状态并正在执行作业。逻辑上有什么问题吗?还有其他可能的方法来实现这一目标吗?我已尽力寻找解决方案。请帮忙。

最佳答案

这是一个棘手的问题。当你的主程序要进入关键部分时,它需要确保:

  1. 调度程序不会再安排任何工作
  2. worker 们已经完成了工作

这两个都需要其他线程的确认。如果您制定某种消息传递机制或使用预先存在的机制,则将其写为通信问题可能会更容易。不过,使用标准的互斥锁和条件变量集,您可能会像这样构造它:

  • 调度程序
    1. 安排工作时,增加正在进行的作业(由互斥体锁定)
  • worker
    1. 完成工作并广播时减少正在进行的作业(由互斥锁锁定)
  • 主要
    1. 当它需要一个关键部分时,它会设置一个标志(由互斥锁锁定),表明关键部分正在进行中,并在 condvar 上广播此状态已更改
    2. 设置一个标志(也被锁定),表明条目正在进行并广播状态更改
    3. 它等待正在进行的条件变量,以便调度程序通过将标志设置为零来确认
    4. 它等待工作进程完成作业
    5. 取消设置正在进行的和广播以解锁调度程序
  • 调度程序
    1. 在开始工作之前或在 condvar 上检查 main 是否想要输入
    2. 取消设置正在进行的标记并广播以确认
    3. 等待 key-in-progress condvar main 完成

当您完成所有这些工作后,main 可以确保不会再安排更多的工作,并且所有正在进行的工作都已完成。它可以做它的事情,然后解锁调度程序。

关于c - 多线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18567272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com