我希望存储整数写入write_odd_queue,然后从另一个线程弹出整数。
data_prepation_thread
函数会将整数存储到write_odd_queue
。
handle_odd
函数将弹出write_odd_queue
的整数。
当我写Sleep(10)
时,内存不会增加。
当我评论此代码时,内存会增加。
请帮我解决这个问题。
#include <iostream>
#include <vector>
#include <thread>
#include <random>
#include <windows.h>
#include <time.h>
#include <mutex>
#include <queue>
#include <condition_variable>
using namespace std;
queue<int> write_odd_queue;
mutex write_odd_mutux;
void handle_odd()
{
while (true)
{
int i;
{
lock_guard<mutex> lk(write_odd_mutux);
if (!write_odd_queue.empty())
{
i = write_odd_queue.front();
write_odd_queue.pop();
cout << "test size " << write_odd_queue.empty() << " ";
}
else
{
continue;
}
}
cout << "odd " << i << endl;
Sleep(500);
}
}
void data_prepation_thread()
{
int i = 0;
while (true)
{
i++;
unique_lock<mutex> lk(write_odd_mutux);
write_odd_queue.push(i);
lk.unlock();
// comment Sleep(10), memory will not increase.
//Sleep(10);
}
}
int main()
{
vector<thread> vec;
thread t1(handle_odd);
vec.push_back(move(t1));
data_prepation_thread();
auto it = vec.begin();
for (; it != vec.end(); ++it)
{
it->join();
}
return 0;
}
答案 0 :(得分:1)
您正在从队列中删除500毫秒的延迟,并将它们毫无延迟地推送到队列 - 这意味着队列将增长,因为您的弹出频率与您的推送频率不匹配。为推送添加延迟将减少增长,因此对于短期运行程序来说可能并不明显。
答案 1 :(得分:1)
这是使用条件变量避免两个函数中Sleep()
的解决方案:
queue<int> write_odd_queue;
mutex write_odd_mutux;
condition_variable data_ready;
condition_variable queue_ready;
bool stopped = false;
const size_t max_size = 1024;
const size_t min_size = 512;
void handle_odd()
{
unique_lock<mutex> lk(write_odd_mutux);
while (!stopped)
{
if( write_odd_queue.empty() ) {
data_ready.wait( lk );
continue;
}
int i = write_odd_queue.front();
write_odd_queue.pop();
if( write_odd_queue.size() == min_size )
queue_ready.notify_one();
cout << "test size " << write_odd_queue.empty() << " ";
lk.unlock();
cout << "odd " << i << endl;
lk.lock();
}
}
void data_prepation_thread()
{
int i = 0;
while (!stopped)
{
unique_lock<mutex> lk(write_odd_mutux);
if( write_odd_queue.size() >= max_size ) {
queue_ready.wait( lk );
continue;
}
write_odd_queue.push(++i);
if( write_odd_queue.size() == 1 )
data_ready.notify_all();
}
}
void stop()
{
unique_lock<mutex> lk(write_odd_mutux);
stopped = true;
data_ready.notify_all();
queue_ready.notify_all();
}
这样可以防止队列长度大于max_size
,并在大小降至min_size
时重新启用。与Sleep(500)
一样,处理也不会造成不必要的延迟。