概要
unique_ptrを要素とするdequeを、スレッド間のデータ受け渡しに使おうとしています。
排他制御にはmutex(lock_guardおよびunique_lock)とcondition_variableを使用しています。
が、受け取りスレッド側におけるunique_lockとunique_ptrの位置関係によって、メモリが解放されていないように見える現象に悩まされています。
原因・解決策について知見をお持ちの方がいらっしゃいましたら、ご回答よろしくお願いいたします。
環境
- Visual Studio Professional 2017
- Visual C++ / Windows コンソール アプリケーション
再現コード
コード中、NG
とコメントしてある箇所でunique_ptrの定義を行うと、メモリ使用量が増加し続けます(タスクマネージャーで確認、送信側でbad_alloc発生)。
本来 NG その1
の箇所で定義・解放を行いたいのですが、NG その2
の箇所で定義しても同様となります。
しかしOK
とコメントしてある箇所で定義した場合は、そのような現象が発生しません。
C++
1#include "stdafx.h" 2#include <cstdint> 3#include <mutex> 4#include <condition_variable> 5#include <deque> 6#include <thread> 7#include <iostream> 8 9using namespace std; 10 11static constexpr auto LENGTH = 2 * 1024 * 1024; 12static mutex mtx; 13static condition_variable cond; 14static deque<unique_ptr<uint8_t[]>> que; 15 16void reader() 17{ 18 while (true) { 19 unique_ptr<uint8_t[]> values; // NG その1 20 21 // Critical section. 22 { 23 //unique_ptr<uint8_t[]> values; // NG その2 24 unique_lock<decltype(mtx)> lock(mtx); 25 //unique_ptr<uint8_t[]> values; // OK 26 27 while (que.empty()) { 28 cond.wait(lock); 29 } 30 31 values = move(que.front()); 32 que.pop_front(); 33 } 34 35 // valuesに対して処理を行う 36 37 this_thread::yield(); 38 } 39} 40void writer() 41{ 42 for (auto i = 0; i <= 100000; ++i) { 43 try { 44 unique_ptr<uint8_t[]> values(new uint8_t[LENGTH]); 45 46 // valuesに対して処理を行う 47 48 // Critical section. 49 { 50 lock_guard<decltype(mtx)> lock(mtx); 51 52 que.push_back(move(values)); 53 cond.notify_one(); 54 } 55 } 56 catch (exception e) { 57 cout << e.what() << endl; 58 } 59 60 this_thread::yield(); 61 } 62} 63 64int main() 65{ 66 unique_ptr<thread> reader_thread(new thread(reader)); 67 unique_ptr<thread> writer_thread(new thread(writer)); 68 69 writer_thread->join(); 70 reader_thread->join(); // infinity 71 72 return 0; 73}
余談
スレッド間で「1回あたり2MB以上」「秒間25回」程度のデータを送受信する、スマートな方法が思いつかずこのようなコードになっています。
送信前に受信側バッファが一定サイズを超えていない事の確認も必要で、何か良い方法がないものでしょうか……。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/08 15:49
2018/02/08 16:53
2018/02/08 17:41