当我使用线程和互斥时,C ++发生内存泄漏

时间:2017-06-14 15:50:33

标签: c++ memory-leaks

我希望存储整数写入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;
}

2 个答案:

答案 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)一样,处理也不会造成不必要的延迟。