2016-03-29 20 views
0

私はマルチスレッドに新しいですし、私は2つのクラスの間での相互作用を同期させるために、スレッドプールのメカニズムを使用していました。ブーストを理解することができません::ミューテックスエラーC++

私はコンパイル中にエラーを理解することができません。

クラスは以下の通りである:

InstrumentProcessor.h

1 #ifndef INSTRUMENTPROCESSOR_H 
    2 #define INSTRUMENTPROCESSOR_H 
    3 
    4 #include <boost/thread/thread.hpp> 
    5 #include <boost/thread/mutex.hpp> 
    6 #include <boost/algorithm/string.hpp> 
    7 #include <boost/lexical_cast.hpp> 
    8 #include "Semaphore.h" 
    9 #include "Instrument.h" 
10 #include <queue> 
11 #include <string> 
12 #include <vector> 
13 
14 
15 class InstrumentProcessor 
16 { 
17   public: 
18   InstrumentProcessor(unsigned int const numThreads); 
19   ~InstrumentProcessor(); 
20   bool Start(); 
21   bool Stop(); 
22   void AddLine(const std::string& LineRead); // Producer 
23 
24   private: 
25   void Process(); // Worker Function 
26   void ProcessLine(std::string& line); // Consumer 
27 
28   private: 
29   unsigned int const numThreads_; 
30   boost::mutex ProcessorMutex_; 
31   boost::thread_group ProcessorGroup_; 
32   Semaphore taskCount_; 
33   std::queue<std::string> Line_; 
34   bool stop_; 
35   std::vector<std::string> elements_; 
36   std::vector<Instrument> Instruments_; 
37 }; 
38 
39 #endif /* INSTRUMENTPROCESSOR_H */ 

InstrumentProcessor.cpp

1 #include "InstrumentProcessor.h" 
    2 
    3 InstrumentProcessor::InstrumentProcessor(unsigned int const numThreads) 
    4 : numThreads_(numThreads), stop_(false) 
    5 { 
    6   Instruments_.reserve(25); 
    7 } 
    8 
    9 InstrumentProcessor::~InstrumentProcessor() 
10 { 
11 
12 } 
13 
14 bool InstrumentProcessor::Start() 
15 { 
16   std::cout << "\nParallel Processing Started ...." << std::endl; 
17   for(unsigned int i=0; i<numThreads_; i++) 
18   { 
19     ProcessorGroup_.create_thread(boost::bind(&InstrumentProcessor ::Process, this)); 
20   } 
21 
22   return true; 
23 } 
24 
25 bool InstrumentProcessor::Stop() 
26 { 
27   stop_ = true; 
28   ProcessorGroup_.join_all(); 
29   std::cout << "\n Parallel Processing Stopped ...." << std::endl; 
30   return stop_; 
31 } 
32 
33 
34 void InstrumentProcessor::Process() 
35 { 
36   while(!stop_) 
37   { 
38     --taskCount_; 
39     std::string currentLine; 
40     { 
41       boost::mutex::scoped_lock lock(ProcessorMutex_); 
42       currentLine = Line_.front(); 
43       Line_.pop(); 
44     } 
45     ProcessLine(currentLine); 
46   } 
47 } 
48 
49 void InstrumentProcessor::AddLine(const std::string& LineRead) 
50 { 
51   boost::mutex::scoped_lock lock(ProcessorMutex_); 
52   Line_.push(LineRead); 
53   ++taskCount_; 
54 } 
55 
56 void InstrumentProcessor::ProcessLine(std::string& line) 
57 { 
58   boost::algorithm::split(elements_, line, boost::is_any_of("\t "), boos t::token_compress_on); 
59   for(unsigned int i=1; i<elements_.size(); i++) 
60   { 
61     if (elements_[i].compare("nan") == 0) 
62       continue; 
63     else 
64     { 
65       double data = boost::lexical_cast<double>(elements_[i] ); 
66       Instruments_[i-1].CleanData(data); // This function makes a call to the Insrument Class member function 
67     } 
68   } 
69 } 

Instrument.h

1 #ifndef INSTRUMENT_H 
    2 #define INSTRUMENT_H 
    3 
    4 #include <iostream> 
    5 #include <boost/thread/mutex.hpp> 
    6 #include <cmath> 
    7 
    8 class Instrument 
    9 { 
10   public: 
11   Instrument(); 
12   ~Instrument(); 
13   bool PopulateData(double& data); 
14   bool CleanData(double& data); 
15   bool PrintData(); 
16 
17   private: 
18   bool getMeanAndStandardDeviation(); 
19 
20   private: 
21   double data_; 
22   int N_; 
23   double Mean_; 
24   double M2_; 
25   double stdDev_; 
26   double InitialValue_; 
27   bool Init_; 
28   boost::mutex InstrumentMutex_; 
29 }; 
30 
31 #endif /* INSTRUMENT_H */ 

Instrument.cpp

1 #include "Instrument.h" 
    2 
    3 Instrument::Instrument() 
    4 : Init_(false), data_(0.0), Mean_(0.0), stdDev_(0.0), InitialValue_(0.0), N_(0 ), M2_(0.0) 
    5 { 
    6 
    7 } 
    8 
    9 Instrument::~Instrument() 
10 { 
11 
12 } 
13 
14 bool Instrument::PopulateData(double& data) 
15 { 
16   data_ = data; 
17   if(!Init_) 
18   { 
19     InitialValue_ = data_; 
20     Init_ = true; 
21     std::cout << "The initial value is: " << InitialValue_ << std: :endl; 
22   } 
23   return true; 
24 } 
25 
26 /* Cleaning Part 2: 
27 * Each data point will be represented as the % change from the initial value. 
28 * This will then be added by 101 so as to get uniform positive value with the 
29 * origin of the data shifted to init_origin + 101 
30 */ 
31 
32 bool Instrument::CleanData(double& data) 
33 { 
34 
35   std::cout << "\nData begin inserted: " << data << std::endl; 
36   boost::mutex::scoped_lock lock(InstrumentMutex_); 
37   PopulateData(data); 
38   data_ = ((data_-InitialValue_)/InitialValue_)*100; 
39   data_ += 101; 
40   getMeanAndStandardDeviation(); 
41   return true; 
42 } 
43 
44 // Welford recurrence relation for tick based mean and standard deviation calc ulation 
45 bool Instrument::getMeanAndStandardDeviation() 
46 { 
47   ++N_; 
48   double delta = data_ - Mean_; 
49   Mean_ += delta/N_; 
50   M2_ += delta*(data_ - Mean_); 
51 
52   if(N_ >= 2) 
53   { 
54     double variance = M2_/(N_-1); 
55     stdDev_ = std::sqrt(variance); 
56   } 
57   return true; 
58 } 
59 
60 bool Instrument::PrintData() 
61 { 
62   std::cout << "\nMean: " << Mean_ << "Std Dev: " << stdDev_ << std::end l; 
63   return true; 
64 } 

私は、次のコンパイル行で上記をコンパイルしています:

g++ -std=c++11 -I /usr/lib/x86_64-linux-gnu -lboost_thread -c InstrumentProcessor.cpp 

以下のエラーで得られます。

In file included from /usr/include/c++/4.8/memory:64:0, 
       from /usr/include/boost/config/no_tr1/memory.hpp:21, 
       from /usr/include/boost/smart_ptr/shared_ptr.hpp:27, 
       from /usr/include/boost/shared_ptr.hpp:17, 
       from /usr/include/boost/date_time/time_clock.hpp:17, 
       from /usr/include/boost/thread/thread_time.hpp:9, 
       from /usr/include/boost/thread/lock_types.hpp:18, 
       from /usr/include/boost/thread/pthread/thread_data.hpp:12, 
       from /usr/include/boost/thread/thread_only.hpp:17, 
       from /usr/include/boost/thread/thread.hpp:12, 
       from InstrumentProcessor.h:4, 
       from InstrumentProcessor.cpp:1: 
/usr/include/c++/4.8/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Instrument; _Args = {Instrument}]’: 
/usr/include/c++/4.8/bits/stl_uninitialized.h:75:53: required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Instrument*>; _ForwardIterator = Instrument*; bool _TrivialValueTypes = false]’ 
/usr/include/c++/4.8/bits/stl_uninitialized.h:117:41: required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<Instrument*>; _ForwardIterator = Instrument*]’ 
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<Instrument*>; _ForwardIterator = Instrument*; _Tp = Instrument]’ 
/usr/include/c++/4.8/bits/stl_vector.h:1142:29: required from ‘std::vector<_Tp, _Alloc>::pointer std::vector<_Tp, _Alloc>::_M_allocate_and_copy(std::vector<_Tp, _Alloc>::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator<Instrument*>; _Tp = Instrument; _Alloc = std::allocator<Instrument>; std::vector<_Tp, _Alloc>::pointer = Instrument*; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’ 
/usr/include/c++/4.8/bits/vector.tcc:75:70: required from ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Instrument; _Alloc = std::allocator<Instrument>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’ 
InstrumentProcessor.cpp:6:25: required from here 
/usr/include/c++/4.8/bits/stl_construct.h:75:7: error: use of deleted function ‘Instrument::Instrument(const Instrument&)’ 
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } 
    ^
In file included from InstrumentProcessor.h:9:0, 
       from InstrumentProcessor.cpp:1: 
Instrument.h:8:7: note: ‘Instrument::Instrument(const Instrument&)’ is implicitly deleted because the default definition would be ill-formed: 
class Instrument 
    ^
Instrument.h:8:7: error: use of deleted function ‘boost::mutex::mutex(const boost::mutex&)’ 
In file included from /usr/include/boost/thread/lock_guard.hpp:11:0, 
       from /usr/include/boost/thread/pthread/thread_data.hpp:11, 
       from /usr/include/boost/thread/thread_only.hpp:17, 
       from /usr/include/boost/thread/thread.hpp:12, 
       from InstrumentProcessor.h:4, 
       from InstrumentProcessor.cpp:1: 
/usr/include/boost/thread/pthread/mutex.hpp:96:9: error: declared here 
     BOOST_THREAD_NO_COPYABLE(mutex) 
     ^

これについての助けになります。方法vector::reserve()

答えて

2

実装Instrumentクラスから移動-コンストラクタまたはコピーコンストラクタのいずれかが必要です。

しかし、そのメンバーInstrumentMutex_がコピー可能でも移動可能でもないので、これらのコンストラクタの両方が(ミューテックスはどちら移動をコピーすることができない)、自動的にクラスに対して生成されないことがあります。

Instrumentクラスの移動コンストラクタを手動でと宣言して、ベクトル演算で使用することができます。ミューテックス部材のBecauase、これはムーブコンストラクタ(ミューテックスが移動できない)ことがないが、ミューテックスの簡単な初期化は、所与の用途に十分です。代わりにベクトル_Instrumentsを作成した後.reserve()メソッドを呼び出すので

あるいは、あなたは正確なサイズで、このベクトルを初期化することがあります。

この初期化は、既に宣言されている Instrumentクラスからのみデフォルトコンストラクタが必要です

InstrumentProcessor::InstrumentProcessor(unsigned int const numThreads) 
    : numThreads_(numThreads), stop_(false), _Instruments(25) 
{ 
} 

サイズのベクトルのコンストラクタは、すべてのベクトルの要素があるという点で.reserve()は異なる作成あなたのケースのためのない適切であり得る、(反対として割り当てに)。しかし、すべての要素の作成がOKであれば、この初期化は、明確に定義されたセマンティック(ミューテックスメンバーは移動されずに再作成されない)のないムーブコンストラクターの定義を避けるため、前のものに対して優先されるべきです。

+1

注:mutexは移動またはコピーできません。 – Nevin

+0

ありがとうございました。これは問題を解決しました – smartinsert

+0

@Nevin:ポイントをありがとう、あなたは正しい:mutexesもコピー可能ではありません。私はこのコメントを使って答えを編集し、**間違った**の代わりに別の解決策を追加しました。 "コンパイラが自動的に移動コンストラクタを生成できるようにします"。 – Tsyvarev

関連する問題