我正在努力学习使用boost线程。我正在尝试创建一个简单的程序,我将数字提供给两个线程上都可用的队列,并将其输出到工作线程上。
我这样做是为了让工作线程关闭,如果我喂它1。
问题是当我调用join时,我的主线程就坐在那里等待工作线程完成。我不想要这个。我希望main继续与worker线程并行执行。
template<typename Data>
class concurrent_queue
{
private:
std::queue<Data> the_queue;
mutable boost::mutex the_mutex;
boost::condition_variable the_condition_variable;
public:
void push(Data const& data)
{
boost::mutex::scoped_lock lock(the_mutex);
the_queue.push(data);
lock.unlock();
the_condition_variable.notify_one();
}
bool empty() const
{
boost::mutex::scoped_lock lock(the_mutex);
return the_queue.empty();
}
bool try_pop(Data& popped_value)
{
boost::mutex::scoped_lock lock(the_mutex);
if(the_queue.empty())
{
return false;
}
popped_value=the_queue.front();
the_queue.pop();
return true;
}
void wait_and_pop(Data& popped_value)
{
boost::mutex::scoped_lock lock(the_mutex);
while(the_queue.empty())
{
the_condition_variable.wait(lock);
}
popped_value=the_queue.front();
the_queue.pop();
}
};
void workerFunc(concurrent_queue<int>* q )
{
while(true)
{
while(!q->empty())
{
int p = -1;
q->wait_and_pop(p);
std::cout << p;
if(p == 1)
{
return;
}
}
}
}
int main(int argc, char* argv[])
{
concurrent_queue<int> m_q;
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc,&m_q);
std::cout << "main: waiting for thread" << std::endl;
m_q.push(6);
m_q.push(11);
workerThread.join();
m_q.push(99); //will not reach here
std::cout << "main: done" << std::endl;
return 0;
}
由于
我希望线程处于活动状态并且正在运行,并且只有当主线程可以随时给出一些时才处理数字。
答案 0 :(得分:2)
join()
函数等待附加线程完成,就像它应该的那样。你的主线程没有理由调用join()
它所在的地方,如果你的目的是让你的程序在程序的生命周期内保持运行(或直到你推动{{1}进入你的队列)。
如果你根本没有1
那个线程,那么当join()
对象超出范围时,线程将被分离。这几乎肯定不是你想要的。通常,多线程程序将在从workerThread
返回之前连接()所有线程。在您的情况下,您需要在调用main
之前专门用信号通知您的线程(通过将1
推入您的队列),以使您的程序干净利落。
以下是一个例子:
join()