我尝试解决一个有趣的问题,如下所述:
编写一个具有N个生成器(N = 1 ... 10),M的控制台应用程序 消费者(M = 1 ... 10)和一个数据队列。每个生产者和消费者都是 单独的线程和所有线程同时工作。制片人 线程睡眠0 ... 100毫秒随机然后它醒来和 生成1到100之间的随机数,然后输入此数字 到数据队列。消费者线程随机休眠0 ... 100毫秒 然后醒来并从队列中取出数字并将其保存到 输出'data.txt'文件。所有数字都附加在文件中 它们以逗号分隔(例如4,67,99,23,...)。当生产者 线程将下一个数字放入数据队列,它检查数据的大小 队列,如果它是> = 100,生产者线程被阻塞,直到 元素数量得到< = 80.当消费者线程想要获取时 消费者线程是数据队列中的下一个数字,其中没有元素 阻止,直到生产者将新元素添加到数据队列中。
当我们开始申请时,我们需要插入N(数量为 生产者)和程序开始后的M(消费者数量) 所有线程。它应该打印数据队列的当前数量的元素 在每一秒。当我们停止程序时,它应该中断所有生产者 并等待所有消费者保存所有排队的数据然后退出程序。
要解决这个问题,除了我写的所有线程安全队列
template <class T>
class global::safe_queue
{
private:
sync* m_sync;
size_t m_lcorner;
size_t m_rcorner;
std::queue<T> m_data;
public:
safe_queue(sync* snc, size_t lcorn, size_t rcorn) :
m_sync(snc),
m_lcorner(lcorn),
m_rcorner(rcorn) {}
~safe_queue()
{
m_sync->lock();
while (m_data.size()){
m_data.pop();
}
m_sync->unlock();
}
size_t size() const
{
m_sync->lock();
size_t sz = m_data.size();
m_sync->unlock();
return sz;
}
size_t front() const
{
m_sync->lock();
T item = m_data.front();
m_sync->unlock();
return item;
}
void push(T item)
{
m_sync->lock();
while(m_data.size() >= m_rcorner) {
m_sync->unlock();
usleep(5);
m_sync->lock();
// conditional wait
//m_sync->wait();
}
m_data.push(item);
if(m_data.size() == 1) {
m_sync->unlock();
// conditional signal
//m_sync->signal();
}
m_sync->unlock();
}
T pop()
{
m_sync->lock();
while(m_data.size() == 0) {
m_sync->unlock();
usleep(5);
m_sync->lock();
// conditional wait
//m_sync->wait();
}
T item = m_data.front();
if(m_data.size() <= m_lcorner) {
m_sync->unlock();
// conditional signal
// m_sync->signal();
}
m_data.pop();
m_sync->unlock();
return item;
}
};
但结果我陷入僵局。有什么问题?