我现在正在为一个c ++队列管理程序工作。我添加了我的虚拟代码和序列图。 SomeClass :: Handler有许多数据数据。所以我必须将所有数据保存到我的队列中。工作人员必须操纵数据才能转换为Command实例。所以我想创建一个从数据生成命令的线程。但是我想将工作线程的数量限制为1,以便命令生成过程的数量始终为1。生成命令后,我想将此命令返回给SomeClass。
我完全混淆了如何实现这个设计。任何帮助将不胜感激。
编辑了更多规范。
`
void MyClass::notify_new_data()
{
// if there are no worker, I want to start new worker
// But how?
}
// I want to limit the number of worker to one.
void MyClass::worker() {
// busy loop, so should I add sleep_for(time) at the bottom of this func?
while(queue.empty() == false) {
MyData data;
{
lock_guard<std::mutex> lock(mtx);
data = queue.pop();
}
// do heavy processing with data
auto command = do_something_in_this thread();
// how to pass this command to SomeClass!?
}
}
// this class is called via aother thread.
void MyClass::push_data(MyData some_data) {
{
lock_guard<std::mutex> lock(mtx);
queue.push(some_data);
}
notify_new_data();
}
void SomeClass::Handler(Data d) {
my_class.push(data);
}
void SomeClass::OnReceivedCommand(Command cmd) {
// receive command
}
答案 0 :(得分:2)
问题不是很清楚。我假设:
您需要一个单个工作线程,它可以异步执行某些操作。
您需要从另一个线程中检索工作线程的计算结果。
如何限制工作线程的数量,而不是避免将数据推送到队列?
查看"thread pooling"。使用从线程安全队列中读取的单个工作线程创建线程池。这几乎就是您MyClass::worker()
正在做的事情。
//忙循环,所以我应该在这个函数的底部添加sleep_for(时间)吗?
您可以使用条件变量和锁定机制来防止忙碌等待,也可以使用成熟的无锁队列实现,例如moodycamel::ConcurrentQueue。
//如何将此命令传递给SomeClass!?
在线程之间传递数据的最干净,最安全的方法是使用futures and promises。 std::future
page on cppreference是一个很好的起点。
//如果没有工人,我想开始新员工
在开始计算之前,我会创建一个包含单个活动工作程序的线程池,这样您就不必检查工作程序是否可用。如果您不能这样做,则表明是否创建了工作人员的std::atomic
标志就足够了。