Multi-threading using boost::thread

I'm currently trying to log real-time data by using boost::thread and a check box. When I check the box, the logging thread starts. When I uncheck, the logging thread stops. The problem arises when I check/uncheck repeatedly and very fast (program crashes, some files aren't logged, etc.). How can I write a reliable thread-safe program where these problems don't occur when repeatedly and quickly checking/unchecking? I also don't want to use join() since this temporarily stops the data input coming from the main thread. In the secondary thread, I'm opening a log file, reading from a socket into a buffer, copying this into another buffer, and then writing this buffer to a log file. I'm thinking that maybe I should use mutex locks for reading/writing. If so, what specific locks should I use? Below is a code snippet:

//Main thread
if(m_loggingCheckBox->isChecked()) {

...

if(m_ThreadLogData.InitializeReadThread(socketInfo))//opens the socket.
//If socket is opened and can be read, start thread.
m_ThreadLogData.StartReadThread();
else
std::cout << "Did not initialize thread\n";
}
else if(!m_loggingCheckBox->isChecked())
{

m_ThreadLogData.StopReadThread();

}

void ThreadLogData::StartReadThread()
{
//std::cout << "Thread started." << std::endl;
m_stopLogThread = false;
m_threadSendData = boost::thread(&ThreadLogData::LogData,this);
}

void ThreadLogData::StopReadThread()
{
m_stopLogThread = true;
m_ReadDataSocket.close_socket(); // close the socket

if(ofstreamLogFile.is_open())
{
ofstreamLogFile.flush(); //flush the log file before closing it.
ofstreamLogFile.close(); // close the log file
}
m_threadSendData.interrupt(); // interrupt the thread
//m_threadSendData.join(); // join the thread. Commented out since this
temporarily stops data input.

}

//secondary thread
bool ThreadLogData::LogData()
{

unsigned short int buffer[1024];
bool bufferflag;
unsigned int iSizeOfBuffer = 1024;
int iSizeOfBufferRead = 0;
int lTimeout = 5;

if(!ofstreamLogFile.is_open())
{
ofstreamLogFile.open(directory_string().c_str(), ios::out);

if(!ofstreamLogFile.is_open())
{
return 0;
}
}

while(!m_stopLogThread)
{
try {
int ret = m_ReadDataSocket.read_sock(&m_msgBuffer.m_buffer
[0],iSizeOfBuffer,lTimeout,&iSizeOfBufferRead);

memcpy(&buffer[0],m_msgBuffer.m_buffer,iSizeOfBufferRead);
bufferflag = m_Buffer.setBuffer(buffer);
if(!bufferflag) return false;
object = &m_Buffer;

unsigned int data = object->getData();

ofstreamLogFile << data << std::endl;

boost::this_thread::interruption_point();

} catch (boost::thread_interrupted& interruption) {
std::cout << "ThreadLogData::LogData(): Caught Interruption thread." << std::endl;
StopReadThread();
} catch (...) {
std::cout << "ThreadLogData::LogData(): Caught Something." << std::endl;
StopReadThread();
}

} // end while()


}



Last edited on
looks like you're using serveral variables across multiple threads (like sockets and stream).

You need to ensure that those variables are protected (usint mutexes) when doing something (like open/close/write/read) with this shared variable.

Otherwise it will indeed crash
Boost ASIO actually has a built-in threading pool for it's resource objects. They've also introduced mutex-free safe threading using something they call a "strand". I would look into it ;)
Topic archived. No new replies allowed.