C++ 如何在收到主线程通知且队列中没有更多任务时停止工作线程

问题描述 投票:0回答:1

我有主线程和工作线程。 主线程将任务添加到线程安全队列中。 工作线程从队列中弹出任务并执行一些操作(工作线程需要 1 秒才能完成一项任务)。

我必须根据以下三个要求更新以下代码。

  1. 主线程应如何通知(通知)工作线程所有任务都已添加到队列中。
  2. 从主线程收到通知并且队列为空(没有更多任务要执行)后如何停止工作线程
  3. 主线程如何等待工作线程完全完成。

下面添加c++代码。

SafeQueue队列;

////////////////////主线程 ////////////////////////////// ///////////////////////

for (int i = 0 ; i < limit ; i++)
{
Task t;
queue.Add(t);
}
//  Main thread can inform that all the tasks are added to queue ?

/////////////////////////////////////////////////////

////////////////////////worker thread

while(1)

{
auto task = queue.waitAndGet();

// perform task which takes 1 sec for each task

}

//////////SafeQueue 实现/////////////////////////////////////

class SafeQueue
{

private:
std::queue<Task> m_memberQueue;

std::mutex  m_memberMutex;

std::condition_variable m_cv;

public:
SafeQueue() {}

void Add(Task const& data)
{
std::unique_lock<std::mutex> lk(m_memberMutex);
m_memberQueue.push(data);

m_cv.notify_one();
}

void waitAndGet(Task& Value) { 
std::unique_lock<std::mutex> lk(m_memberMutex);
while (m_memberQueue.empty()) {

     m_cv.wait(Lock);
}

  Value = m_memberQueue.front();
  m_memberQueue.pop();
}

}

我必须根据以下三个要求更新以下代码。

  1. 主线程应如何通知(通知)工作线程所有任务都已添加到队列中。
  2. 从主线程收到通知并且队列为空(没有更多任务要执行)后如何停止工作线程
  3. 主线程如何等待工作线程完全完成。
c++ multithreading thread-safety
1个回答
0
投票

主线程应该如何通知工作线程所有任务都已添加到队列中?

我最喜欢的技巧是古老的“毒丸”方法。将工作人员认为特殊的东西放入队列中。如果预先知道工人的数量,那么顶层可以将与工人数量一样多的毒丸添加到队列中。如果工人的数量不容易知道,那么只需将一颗药丸放入队列中,并让每个工人处理完后重新插入。这样,他们都会一一收到消息。

从主线程收到通知并且队列为空(没有更多任务要执行)后如何停止工作线程

任何线程都不应该强迫另一个线程做任何事情。线程应该合作。如果你想让一个线程死掉,你应该
要求

它死掉,然后让线程自杀。 如果您使用毒丸方法,则很简单:在线程吞下药丸后(并且可以选择将新药丸放入队列中以供下一个工人吞咽),它就会结束。

主线程如何等待工作线程完全完成?

这就是
thread.join()

的用途。

thread.join()
等待
thread
结束。
    

© www.soinside.com 2019 - 2024. All rights reserved.