I am trying to link several binaries to Analysis with an underlying thread pool construct, using the following command:
g++ -std=c++11 -I /usr/lib/x86_64-linux-gnu -lboost_thread Semaphore.cpp InstrumentReader.cpp InstrumentProcessor.cpp InstrumentManager.cpp Instrument.cpp main.cpp -o Analysis
This yields in the below errors which i am not able to decipher.
lboost_thread Semaphore.cpp InstrumentReader.cpp InstrumentProcessor.cpp InstrumentManager.cpp Instrument.cpp main.cpp -o Analysis
/tmp/ccPN4zBw.o: In function `Semaphore::Semaphore()':
Semaphore.cpp:(.text+0x1e): undefined reference to `sem_init'
/tmp/ccPN4zBw.o: In function `Semaphore::~Semaphore()':
Semaphore.cpp:(.text+0x38): undefined reference to `sem_destroy'
/tmp/ccPN4zBw.o: In function `Semaphore::GetOrWait()':
Semaphore.cpp:(.text+0x52): undefined reference to `sem_wait'
/tmp/ccPN4zBw.o: In function `Semaphore::operator++()':
Semaphore.cpp:(.text+0x7a): undefined reference to `sem_getvalue'
Semaphore.cpp:(.text+0x86): undefined reference to `sem_post'
/tmp/ccPN4zBw.o: In function `Semaphore::operator--()':
Semaphore.cpp:(.text+0xb2): undefined reference to `sem_getvalue'
Semaphore.cpp:(.text+0xbe): undefined reference to `sem_wait'
/tmp/ccPN4zBw.o: In function `Semaphore::value()':
Semaphore.cpp:(.text+0xea): undefined reference to `sem_getvalue'
/tmp/cc4PBKug.o: In function `__static_initialization_and_destruction_0(int, int)':
InstrumentReader.cpp:(.text+0x26b): undefined reference to `boost::system::generic_category()'
InstrumentReader.cpp:(.text+0x277): undefined reference to `boost::system::generic_category()'
InstrumentReader.cpp:(.text+0x283): undefined reference to `boost::system::system_category()'
/tmp/cczXEYF9.o: In function `__static_initialization_and_destruction_0(int, int)':
InstrumentProcessor.cpp:(.text+0x630): undefined reference to `boost::system::generic_category()'
InstrumentProcessor.cpp:(.text+0x63c): undefined reference to `boost::system::generic_category()'
InstrumentProcessor.cpp:(.text+0x648): undefined reference to `boost::system::system_category()'
/tmp/cczXEYF9.o: In function `boost::thread_exception::thread_exception(int, char const*)':
InstrumentProcessor.cpp:(.text._ZN5boost16thread_exceptionC2EiPKc[_ZN5boost16thread_exceptionC5EiPKc]+0x14): undefined reference to `boost::system::system_category()'
/tmp/cczXEYF9.o: In function `boost::condition_error::condition_error(int, char const*)':
InstrumentProcessor.cpp:(.text._ZN5boost15condition_errorC2EiPKc[_ZN5boost15condition_errorC5EiPKc]+0x14): undefined reference to `boost::system::system_category()'
/tmp/cczXEYF9.o: In function `boost::detail::thread_data_base::thread_data_base()':
InstrumentProcessor.cpp:(.text._ZN5boost6detail16thread_data_baseC2Ev[_ZN5boost6detail16thread_data_baseC5Ev]+0x24): undefined reference to `vtable for boost::detail::thread_data_base'
/tmp/cczXEYF9.o: In function `boost::detail::interruption_checker::interruption_checker(pthread_mutex_t*, pthread_cond_t*)':
InstrumentProcessor.cpp:(.text._ZN5boost6detail20interruption_checkerC2EP15pthread_mutex_tP14pthread_cond_t[_ZN5boost6detail20interruption_checkerC5EP15pthread_mutex_tP14pthread_cond_t]+0x16): undefined reference to `boost::detail::get_current_thread_data()'
/tmp/cczXEYF9.o: In function `boost::thread::start_thread()':
InstrumentProcessor.cpp:(.text._ZN5boost6thread12start_threadEv[_ZN5boost6thread12start_threadEv]+0x15): undefined reference to `boost::thread::start_thread_noexcept()'
/tmp/cczXEYF9.o: In function `boost::thread::~thread()':
InstrumentProcessor.cpp:(.text._ZN5boost6threadD2Ev[_ZN5boost6threadD5Ev]+0x14): undefined reference to `boost::thread::detach()'
/tmp/cczXEYF9.o: In function `boost::thread::get_id() const':
InstrumentProcessor.cpp:(.text._ZNK5boost6thread6get_idEv[_ZNK5boost6thread6get_idEv]+0x18): undefined reference to `boost::thread::native_handle()'
/tmp/cczXEYF9.o: In function `boost::thread::join()':
InstrumentProcessor.cpp:(.text._ZN5boost6thread4joinEv[_ZN5boost6thread4joinEv]+0x6d): undefined reference to `boost::thread::join_noexcept()'
/tmp/cczXEYF9.o: In function `boost::condition_variable::wait(boost::unique_lock<boost::mutex>&)':
InstrumentProcessor.cpp:(.text._ZN5boost18condition_variable4waitERNS_11unique_lockINS_5mutexEEE[_ZN5boost18condition_variable4waitERNS_11unique_lockINS_5mutexEEE]+0x8b): undefined reference to `boost::this_thread::interruption_point()'
/tmp/cczXEYF9.o: In function `boost::shared_mutex::lock_shared()':
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex11lock_sharedEv[_ZN5boost12shared_mutex11lock_sharedEv]+0x15): undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex11lock_sharedEv[_ZN5boost12shared_mutex11lock_sharedEv]+0x7c): undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex11lock_sharedEv[_ZN5boost12shared_mutex11lock_sharedEv]+0x9e): undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
/tmp/cczXEYF9.o: In function `boost::shared_mutex::lock()':
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex4lockEv[_ZN5boost12shared_mutex4lockEv]+0x15): undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex4lockEv[_ZN5boost12shared_mutex4lockEv]+0x86): undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
InstrumentProcessor.cpp:(.text._ZN5boost12shared_mutex4lockEv[_ZN5boost12shared_mutex4lockEv]+0xa8): undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
/tmp/cczXEYF9.o: In function `boost::thread_group::join_all()':
InstrumentProcessor.cpp:(.text._ZN5boost12thread_group8join_allEv[_ZN5boost12thread_group8join_allEv]+0x59): undefined reference to `boost::thread::joinable() const'
/tmp/cczXEYF9.o: In function `boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, InstrumentProcessor>, boost::_bi::list1<boost::_bi::value<InstrumentProcessor*> > > >::~thread_data()':
InstrumentProcessor.cpp:(.text._ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv19InstrumentProcessorEENS2_5list1INS2_5valueIPS6_EEEEEEED2Ev[_ZN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv19InstrumentProcessorEENS2_5list1INS2_5valueIPS6_EEEEEEED5Ev]+0x1f): undefined reference to `boost::detail::thread_data_base::~thread_data_base()'
/tmp/cczXEYF9.o:(.rodata._ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv19InstrumentProcessorEENS2_5list1INS2_5valueIPS6_EEEEEEEE[_ZTIN5boost6detail11thread_dataINS_3_bi6bind_tIvNS_4_mfi3mf0Iv19InstrumentProcessorEENS2_5list1INS2_5valueIPS6_EEEEEEEE]+0x10): undefined reference to `typeinfo for boost::detail::thread_data_base'
/tmp/ccQvaI09.o: In function `__static_initialization_and_destruction_0(int, int)':
InstrumentManager.cpp:(.text+0x23b): undefined reference to `boost::system::generic_category()'
InstrumentManager.cpp:(.text+0x247): undefined reference to `boost::system::generic_category()'
InstrumentManager.cpp:(.text+0x253): undefined reference to `boost::system::system_category()'
/tmp/ccxHiUTc.o: In function `__static_initialization_and_destruction_0(int, int)':
Instrument.cpp:(.text+0x56c): undefined reference to `boost::system::generic_category()'
Instrument.cpp:(.text+0x578): undefined reference to `boost::system::generic_category()'
Instrument.cpp:(.text+0x584): undefined reference to `boost::system::system_category()'
/tmp/cclT6aOm.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x106): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x112): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x11e): undefined reference to `boost::system::system_category()'
collect2: error: ld returned 1 exit status
The relevant class details are as below: Semaphore.h:
#ifndef SEMAPHORE_H
#define SEMAPHORE_H
#include <semaphore.h>
class Semaphore
{
public:
Semaphore();
~Semaphore();
void GetOrWait();
//pre-increment
int operator++ ();
//pre-decrement
int operator-- ();
int value();
private:
sem_t semaphore_;
// Removed copy constructor and copy assignment operator
Semaphore(const Semaphore &){}
Semaphore& operator = (const Semaphore &){return *this;}
};
#endif /* SEMAPHORE_H */
Semaphore.cpp:
#include "Semaphore.h"
Semaphore::Semaphore()
{
sem_init(&semaphore_, 0, 0); // Non-Shared, Initial Value = 0
}
Semaphore::~Semaphore()
{
sem_destroy(&semaphore_);
}
/* If the semaphore's value is greater than zero, then the decrement proceeds,
* and the function returns, immediately.
* If the semaphore currently has the value zero, then the call blocks
* until it becomes possible to perform the decrement.
*/
void Semaphore::GetOrWait()
{
sem_wait(&semaphore_);
}
// pre-increment
int Semaphore::operator++ ()
{
int value = 0;
sem_getvalue(&semaphore_, &value);
sem_post(&semaphore_);
return value;
}
// pre-decrement
int Semaphore::operator--()
{
int value = 0;
sem_getvalue(&semaphore_, &value);
sem_wait(&semaphore_);
return value;
}
int Semaphore::value()
{
int value = 0;
sem_getvalue(&semaphore_, &value);
return value;
}
InstrumentProcessor.h
#ifndef INSTRUMENTPROCESSOR_H
#define INSTRUMENTPROCESSOR_H
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "Semaphore.h"
#include "Instrument.h"
#include <queue>
#include <string>
#include <vector>
#include <atomic>
class InstrumentProcessor
{
public:
InstrumentProcessor(unsigned int const numThreads);
~InstrumentProcessor();
bool Start();
bool Stop();
bool getStop();
void AddLine(const std::string& LineRead); // Producer
private:
void Process(); // Worker Function
void ProcessLine(std::string& line); // Consumer
private:
unsigned int const numThreads_;
boost::mutex ProcessorMutex_;
boost::thread_group ProcessorGroup_;
Semaphore taskCount_;
std::queue<std::string> Line_;
std::atomic<bool> stop_;
std::vector<std::string> elements_;
std::vector<Instrument> Instruments_;
};
#endif /* INSTRUMENTPROCESSOR_H */
InstrumentProcessor.cpp
#include "InstrumentProcessor.h"
InstrumentProcessor::InstrumentProcessor(unsigned int const numThreads)
: numThreads_(numThreads), stop_(false)
{
Instruments_.reserve(25);
}
InstrumentProcessor::~InstrumentProcessor()
{
}
bool InstrumentProcessor::Start()
{
std::cout << "\nParallel Processing Started ...." << std::endl;
for(unsigned int i=0; i<numThreads_; i++)
{
ProcessorGroup_.create_thread(boost::bind(&InstrumentProcessor::Process, this));
}
return true;
}
bool InstrumentProcessor::Stop()
{
stop_ = true;
ProcessorGroup_.join_all();
std::cout << "\n Parallel Processing Stopped ...." << std::endl;
return stop_;
}
void InstrumentProcessor::Process()
{
while(!stop_)
{
--taskCount_;
std::string currentLine;
{
boost::mutex::scoped_lock lock(ProcessorMutex_);
currentLine = Line_.front();
Line_.pop();
}
ProcessLine(currentLine);
}
}
void InstrumentProcessor::AddLine(const std::string& LineRead)
{
boost::mutex::scoped_lock lock(ProcessorMutex_);
Line_.push(LineRead);
++taskCount_;
}
void InstrumentProcessor::ProcessLine(std::string& line)
{
boost::algorithm::split(elements_, line, boost::is_any_of("\t "), boost::token_compress_on);
for(unsigned int i=1; i<elements_.size(); i++)
{
if (elements_[i].compare("nan") == 0)
continue;
else
{
double data = boost::lexical_cast<double>(elements_[i]);
Instruments_[i-1].CleanData(data);
}
}
}
bool InstrumentProcessor::getStop()
{
return stop_;
}
InstrumentManager.h
#ifndef INSTRUMENTMANAGER_H
#define INSTRUMENTMANAGER_H
#include "InstrumentProcessor.h"
#include "InstrumentReader.h"
#include <string>
class InstrumentManager
{
public:
InstrumentManager(std::string& filename);
~InstrumentManager();
bool Start();
private:
InstrumentManager(const InstrumentManager& manager);
InstrumentManager& operator=(const InstrumentManager& manager);
private:
std::string filename_;
InstrumentReader Reader_;
InstrumentProcessor* Processor_;
};
#endif /* INSTRUMENTMANAGER_H */
InstrumentManager.cpp
#include "InstrumentManager.h"
InstrumentManager::InstrumentManager(std::string& filename)
: filename_(filename), Processor_(new InstrumentProcessor(5)), Reader_(filename_, Processor_)
{
}
InstrumentManager::InstrumentManager(const InstrumentManager& manager)
:filename_(manager.filename_), Processor_(new InstrumentProcessor(5)), Reader_(filename_, manager.Processor_)
{
}
InstrumentManager& InstrumentManager::operator=(const InstrumentManager& manager)
{
return *this;
}
InstrumentManager::~InstrumentManager()
{
delete Processor_;
}
bool InstrumentManager::Start()
{
Reader_.GetLinesFromFile();
Processor_->Start();
return true;
}
Instrument.h
#ifndef INSTRUMENT_H
#define INSTRUMENT_H
#include <iostream>
#include <boost/thread/mutex.hpp>
#include <cmath>
class Instrument
{
public:
Instrument();
Instrument(Instrument&& instrument);
~Instrument();
bool PopulateData(double& data);
bool CleanData(double& data);
double getMean();
double getData();
double getDev();
bool PrintData();
private:
bool getMeanAndStandardDeviation();
private:
double data_;
int N_;
double Mean_;
double M2_;
double stdDev_;
double InitialValue_;
bool Init_;
boost::mutex InstrumentMutex_;
};
#endif /* INSTRUMENT_H */
Instrument.cpp
#include "Instrument.h"
Instrument::Instrument()
: Init_(false), data_(0.0), Mean_(0.0), stdDev_(0.0), InitialValue_(0.0), N_(0), M2_(0.0)
{
}
Instrument::Instrument(Instrument&& instrument)
: Init_(std::move(instrument.Init_)), data_(std::move(instrument.data_)),
Mean_(std::move(instrument.Mean_)), stdDev_(std::move(instrument.stdDev_)),
InitialValue_(std::move(instrument.InitialValue_)), N_(std::move(instrument.N_)), M2_(std::move(instrument.M2_))
{
}
Instrument::~Instrument()
{
}
bool Instrument::PopulateData(double& data)
{
data_ = data;
if(!Init_)
{
InitialValue_ = data_;
Init_ = true;
std::cout << "The initial value is: " << InitialValue_ << std::endl;
}
return true;
}
/* Cleaning Part 2:
* Each data point will be represented as the % change from the initial value.
* This will then be added by 101 so as to get uniform positive value with the
* origin of the data shifted to init_origin + 101
*/
bool Instrument::CleanData(double& data)
{
std::cout << "\nData begin inserted: " << data << std::endl;
boost::mutex::scoped_lock lock(InstrumentMutex_);
PopulateData(data);
data_ = ((data_-InitialValue_)/InitialValue_)*100;
data_ += 101;
getMeanAndStandardDeviation();
return true;
}
// Welford recurrence relation for tick based mean and standard deviation calculation
bool Instrument::getMeanAndStandardDeviation()
{
++N_;
double delta = data_ - Mean_;
Mean_ += delta/N_;
M2_ += delta*(data_ - Mean_);
if(N_ >= 2)
{
double variance = M2_/(N_-1);
stdDev_ = std::sqrt(variance);
}
return true;
}
double Instrument::getData()
{
boost::mutex::scoped_lock lock(InstrumentMutex_);
return data_;
}
double Instrument::getMean()
{
boost::mutex::scoped_lock lock(InstrumentMutex_);
return Mean_;
}
double Instrument::getDev()
{
boost::mutex::scoped_lock(InstrumentMutex_);
return stdDev_;
}
bool Instrument::PrintData()
{
std::cout << "\nMean: " << Mean_ << "Std Dev: " << stdDev_ << std::endl;
return true;
}
main.cpp
#include <iostream>
#include <string>
#include "InstrumentManager.h"
int main()
{
std::string filename = "data_format.txt";
InstrumentManager mgr(filename);
mgr.Start();
return 0;
}
Any help is much appreciated.
Aucun commentaire:
Enregistrer un commentaire