当前位置: 首页 > 知识库问答 >
问题:

使用互斥体将一次运行的线程数限制为2

郭永怡
2023-03-14

我有一个程序,把10个线程推到一个向量中,每个线程在完成之前要打印出一个字符5次(第一个线程是'a',第二个线程是'B',等等)。我可以让它们一次全部运行(使用detach())或者一次运行一个(使用join())。现在我想使用互斥体将一次允许打印的线程数限制为2。我已经能够声明互斥体并将锁放在适当的位置,但我不确定如何应用这样的限制。有人对如何继续有什么想法吗?

deque<int> q ;
mutex print_mutex ;
mutex queue_mutex ;
condition_variable queue_cond ;

void begin(int num) {
    unique_lock<mutex> ul {queue_mutex};
    q.emplace_back(num);
    queue_cond.wait(ul,[num]{
        return q.front() == num; });
    q.pop_front();
    cout << num << " leaves begin " << endl ;
}

void end ( int num ) {
    lock_guard<mutex>lg{queue_mutex};
    queue_cond.notify_all();
    cout << num << " has ended " << endl ;
}

void run(int num, char ch) {
    begin(num);
    for (int i = 0; i < 5; ++i) {
        {
            lock_guard<mutex> lg { print_mutex };
            cout << ch << endl << flush ;
        }
        sleep_for(milliseconds(250));
    }
    end(num);
}

int main() {
    vector<thread>threads {};
    for (int i = 0; i < 10; ++i) {
        threads.push_back(thread{run,i,static_cast<char>(65+i)});
        threads.at(i).join();
    }
}

共有1个答案

颛孙航
2023-03-14

您已经使用全局deque q 为线程设置了FIFO。让我们利用这个。

当前,您正在尝试限制执行,直到当前线程位于前面。但因为begin会立即从Deque弹出线程。最好在调用end时删除该值。首先,这是一个变化:

void end(int num)
{
    {
        lock_guard<mutex>lg{queue_mutex};
        cout << num << " has ended " << endl ;
        q.erase(find(q.begin(), q.end(), num));
    }
    queue_cond.notify_all();
}

这将使用 gorith>中的std::find移除特定值。您可以使用pop_front,但我们将更改该逻辑,使其更通用。还请注意,在通知时不需要锁定条件变量。

void begin(int num)
{
    unique_lock<mutex> ul {queue_mutex};
    q.emplace_back(num);
    queue_cond.wait(ul,[num]{
        auto end = q.begin() + std::min(2, static_cast<int>(q.size()));
        return find(q.begin(), end, num) != end;
        });
    cout << num << " leaves begin " << endl ;
}
for (int i = 0; i < 10; ++i) {
    threads.push_back( thread{run, i, 'A'+i} );
}
for (auto & t : threads) t.join();
 类似资料:
  • 问题内容: 是多线程/进程编程的新手。所以这是我需要澄清的。 处理代码 使用上述伪代码,如果互斥锁未解锁,进程B是否可以访问? 如何从进程B正确访问sharedResource? 有没有清晰的可视化图表说明互斥体,线程和进程之间的关系? 问题答案: 您需要做的是调用pthread_mutex_lock来保护互斥锁,如下所示: 一旦执行此操作,在您在该线程中进行调用之前,不会再进行任何其他调用。因此

  • 问题内容: 我想创建一个运行多个轻线程的程序,但将其自身限制为恒定的,预定义数量的并发运行任务,如下所示(但不存在竞争条件的风险): 最安全/最快的方法是什么? 问题答案: 听起来您想用8个工人实现生产者/消费者模式。Python为此提供了一个类,它是线程安全的。 每个工作人员都应调用队列以检索任务。如果没有可用的任务,此调用将阻塞,从而导致工作人员空闲直到可用。然后,工作人员应执行任务,最后在队

  • 现在当这个程序运行时,我得到以下输出: 现在我知道这个问题以前已经被问过很多次了,但是有什么方法可以强制解锁互斥锁吗?似乎该实现只允许锁互斥体的线程在主动检查时解锁互斥体,即使使用普通互斥体类型也是如此。 我为什么要这么做?它与编写一个防弹网络服务器有关,该服务器能够从大多数错误中恢复,包括线程意外终止的错误。在这一点上,我看不到从不同于锁定互斥体的线程解锁互斥体的方法。所以在我看来,我有几个选择

  • 类型 pthread_mutex_t 互斥锁基本操作 函数 描述 [[pthread_mutex_init pthread_mutex_init]] 初始化互斥锁 [[pthread_mutex_lock pthread_mutex_lock]] 阻塞申请互斥锁 [[pthread_mutex_unlock pthread_mutex_unlock]] 释放互斥锁 [[pthread_mutex_

  • 本文向大家介绍Python多线程编程(四):使用Lock互斥锁,包括了Python多线程编程(四):使用Lock互斥锁的使用技巧和注意事项,需要的朋友参考一下 前面已经演示了Python:使用threading模块实现多线程编程二两种方式起线程和Python:使用threading模块实现多线程编程三threading.Thread类的重要函数,这两篇文章的示例都是演示了互不相干的独立线程,现在我

  • 问题内容: 我想知道Node.js中的数据访问是否需要互斥锁/锁。例如,假设我已经创建了一个简单的服务器。服务器提供了几种协议方法,可以添加到内部阵列中或从内部阵列中删除。我需要使用某种互斥量保护内部阵列吗? 我了解Javascript(因此Node.js)是单线程的。我只是不清楚事件的处理方式。事件会中断吗?如果真是这样,我的应用程序可能正在读取数组的过程中,被打断以运行事件回调以更改数组,然后