Can Detaching A Thread Lead To A Torn Write - c++

Good day,
I am new to threading, and I am wondering if I have something like (context of C++, and X threading library):
//Pseudo code...//
void OnThread() {
someGlobalVar = 2;
someGlobalVar += 4;
}
void main()
{
ThreadHandle someThreadHandle = MakeThread( &OnThread );
//Can a torn write occur?//
someThreadHandle.Detach();
//Can "someGlobalVar" be trusted?//
std::cerr << someGlobalVar << "\n";
return ( 0 );
}
Could someGlobalVar have a torn write applied to it, can it be considered "safe" after the detach?

It is safe to detach a thread as long as your program is still running, The thread will keep running after you detach it. But it would be safer to use a join which will block until the thread is done executing.

Related

POSIX Threads - synchronize DETACHED threads using conditional variable MEMORY LEAK

Hello I'm trying to synchronize detached threads using conditional variable, but I found a bug that sometimes causes memory leak (depends on scheduler mood). I think the code is self explanatory. I would appreciate any advice.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
using namespace std;
struct TThrArg
{
pthread_t m_ID;
bool m_IsRunning;
};
TThrArg g_Threads[64];
int g_Counter;
pthread_mutex_t g_Mtx;
pthread_cond_t g_Cond;
void * thrFunc ( void * arg )
{
TThrArg * data = (TThrArg *) arg;
// do some stuff
// -----------------------------------
// for ( int i = 0; i < 5000; ++i )
// for ( int j = 0; j < 5000; ++j )
// int x = 0;
// printf("Thread: %lu running...\n", data->m_ID);
// -----------------------------------
pthread_mutex_lock(&g_Mtx);
memset(data, 0, sizeof(TThrArg));
--g_Counter;
pthread_cond_signal(&g_Cond);
pthread_mutex_unlock(&g_Mtx);
sleep(1); // --> this spot causes that main may end before return NULL so resources will not be freed
return NULL;
}
void createThread ( void )
{
pthread_mutex_lock(&g_Mtx);
for ( int i = 0; i < 64; ++i )
{
if ( g_Threads[i].m_IsRunning == 0 )
{
g_Threads[i].m_IsRunning = 1;
++g_Counter;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&g_Threads[i].m_ID, &attr, thrFunc, &g_Threads[i]);
pthread_attr_destroy(&attr);
break;
}
}
pthread_mutex_unlock(&g_Mtx);
}
int main ( int argc, char * argv[] )
{
pthread_mutex_init(&g_Mtx, NULL);
pthread_cond_init(&g_Cond, NULL);
g_Counter = 0;
for ( int i = 0; i < 64; ++i )
createThread();
pthread_mutex_lock(&g_Mtx);
while ( g_Counter != 0 )
{
pthread_cond_wait(&g_Cond, &g_Mtx);
}
pthread_mutex_unlock(&g_Mtx);
pthread_mutex_destroy(&g_Mtx);
pthread_cond_destroy(&g_Cond);
return 0;
}
The leak you see is because the terminating thread decrements the mutex-protected thread counter, and pauses for a second before the thread actually terminates.
The main execution thread will immediately see that the thread counter reached 0, and terminate before the actual detached threads have exited. Each running thread, even a detached thread, consumes and allocates a little bit of internal memory, which does not get released until the thread actually terminates. This is the leak you see, from execution threads that did not terminate before the main execution thread stopped.
This is not the kind of a leak that you need to worry about. It is rather annoying, and makes debugging difficult, true.
In the past, I took one approach in a framework class library that I wrote some time ago. I did not use detached threads at all, but all threads were joinable threads. The framework started one singleton background thread whose only job was to join() the terminated threads. Then, each thread started by the framework will queue up its own thread id for the singleton background thread, just before each thread terminates.
The net effect was equivalent to detached threads. I could start each thread and not worry about joining to it. It's going to be the background thread's job. The framework would signal the background thread to terminate itself, and join it, before exiting. So, if all goes well, there will not be any reported memory leaks that can be accounted to thread support.

Kill an std::thread that wasn't joined

So I have a thread that I was running using .join() but I needed an interactive user interface while running the thread so I stopped using join because it halted the program while it ran. The ui has a stop button to kill the thread and now I need a way to stop the thread without killing the whole program because I can't use .detach(). Thanks!
There is no safe way to unilaterally terminate a thread. Instead, the thread's code must periodically check whether the GUI thread has requested that it exit.
I'm not familiar with the new C++ library functions, but I believe you can do this with atomic_bool, e.g., see this question.
you could pass a reference to a bool variable to the thread and check if it is true. if it is, return from the thread.
Example:
bool terminate = false;
std::mutex m;
std::thread t([&terminate,&m] {
std::unique_lock<std::mutex> lm{m,std::defer_lock}; //don't lock yet
int i = 0;
while (true) {
lm.lock(); //protect terminate -> no race conditions
if (terminate)
return;
lm.unlock(); //release lock for terminate
//do what your thread should do
std::cout << i++ << std::endl;
}
});
/*
do something else here
*/
m.lock();
terminate = true;
m.unlock();
t.join();

The conditional variable is not working but after adding std::cout, it is working

My project is consists of two threads: one main thread and the other thread which handles another window content. So, the when the main thread wants to ask the another windows to update itself it calls the draw function which is as follows:
void SubApplicationManager::draw() {
// Zero number of applications which has finished the draw counter
{
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
SubApplication::num_draws = 0;
}
// Draw the sub applications.
for (size_t i = 0; i < m_subApplications.size(); i++)
m_subApplications[i].signal_draw();
// Wait until all the sub applications finish drawing.
while (true){
boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
std::cout << SubApplication::num_draws << std::endl;
if (SubApplication::num_draws >= m_subApplications.size()) break;
}
}
The draw function just signals the other thread that a new task is received.
void SubApplication::signal_draw() {
task = TASK::TASK_DRAW;
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
}
task_start_condition.notify_all();
}
The body of other thread is as follows. It waits for the task to arrive and then start to process:
void SubApplication::thread() {
clock_t start_time, last_update;
start_time = last_update = clock();
//! Creates the Sub Application
init();
while (!done) // Loop That Runs While done=FALSE
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
// Wait here, until a update/draw command is received.
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
// Task received is set to false, for next loop.
{
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = false;
}
clock_t frame_start_time = clock();
switch (task){
case TASK_UPDATE:
update();
break;
case TASK_DRAW:
draw();
swapBuffers();
break;
case TASK_CREATE:
create();
break;
default:
break;
}
clock_t frame_end_time = clock();
double task_time = static_cast<float>(frame_end_time - frame_start_time) / CLOCKS_PER_SEC;
}
}
}
The problem is that if I run the code as it is, it never runs the other thread with task = TASK::TASK_DRAW; but if I add a std::cout << "Draw\n"; to the beginning of SubApplication::draw(), it will work as it should. I am looking for the reason which it is happening and what is the usual way to fix it?
boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;
Okay, the task_received_mutex protects task_received.
boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
while (!task_received){
task_start_condition.wait(start_lock);
}
Oops, we're reading task_received without holding the mutex that protects it. What prevents a race where one thread reads task_received while another thread is modifying it? This could immediately lead to deadlock.
Also, you have code that claims to "Wait until all the sub applications finish drawing" but there's no call to any wait function. So it actually spins rather than waiting, which is awful.
As a starter, signal the task_start_condition under the task_start_mutex lock.
Consider locking that mutex during thread creation to avoid obvious races.
Third: it seems you have several mutexes named for "logical tasks" (draw, start). In reality, however, mutexes guard resources, not "logical tasks". So it's good practice to name them after the shared resource they should guard. _(In this case I get the impression that a single mutex could be enough/better. But we can't tell for sure from the code shown)).

How to control reading from file using performance counters?

There are several operations being done on drive G. My program should read data from file. When the disk usage is very high(>90%) the program should slow down the reading so it won't interfere with other processes that uses the disk. Obviously, I guess, that checking the Disk Time after calling get_data_from_file() will cause the counter to return very high percentage because the disk was just used. You can see that on the image.
Any suggestions on how I can check correctly the Disk Time?
PDH_HQUERY query;
PDH_HCOUNTER counter;
PdhOpenQuery(NULL, 0, &query);
PdhAddCounterA(query, "\\LogicalDisk(G:)\\% Disk Time", 0, &counter);
PdhCollectQueryData(query);
auto getDiskTime = [&]()->double
{
PDH_FMT_COUNTERVALUE fmtCounter;
PdhCollectQueryData(query);
PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, 0, &fmtCounter);
return fmtCounter.doubleValue;
};
for(...)
{
get_data_from_file();
print_done_percentage();
double diskUsage = getDiskTime();
if(diskUsage >= 90)
{
std::cout << "The disk usage is over << diskUsage << "%. I'll wait...
while(diskUsage >= 90)
{
diskUsage = getDiskTime();
Sleep(500);
}
}
}
A distinct monitoring thread could help you measure disk usage with more independence from the writing.
The function executed by the thread would look like this:
void diskmonitor(atomic<double>& du, const atomic<bool>& finished) {
while (!finished) { // stop looping as soon as main process has finished job
du = getDiskTime(); // measure disk
this_thread::sleep_for(chrono::milliseconds(500)); //wait
}
}
It communicates with the main thread through atomic (i.e. to avoid data races) variables passed by reference.
Your processing loop would look as follows:
atomic<bool> finished=false; // tell diskmonitor that the processing is ongoing
atomic<double> diskusage=0; // last disk usage read by diskmonitor
thread t(diskmonitor, ref(diskusage), ref(finished)); // launch monitor
for (int i = 0; i < 1000; i++)
{
...
print_done_percentage();
while (diskusage >= 90) { // disk usage is filled in background
std::cout << "The disk usage is over " << diskusage << ".I'll wait...\n";
this_thread::sleep_for(chrono::milliseconds(500));
}
...
}
finished = false; // tell diskmonitor that i't's finished, so that it ends the loop
t.join(); // wait until diskmonitor is finished.
This example is with standard C++ threads. Of course you could code something similar with OS specific threads.

Closing a thread with select() system call statement?

I have a thread to monitor serial port using select system call, the run function of the thread is as follows:
void <ProtocolClass>::run()
{
int fd = mPort->GetFileDescriptor();
fd_set readfs;
int maxfd=fd+1;
int res;
struct timeval Timeout;
Timeout.tv_usec=0;
Timeout.tv_sec=3;
//BYTE ack_message_frame[ACKNOWLEDGE_FRAME_SIZE];
while(true)
{
usleep(10);
FD_ZERO(&readfs);
FD_SET(fd,&readfs);
res=select(maxfd,&readfs,NULL,NULL,NULL);
if(res<0)
perror("\nselect failed");
else if( res==0)
puts("TIMEOUT");
else if(FD_ISSET(fd,&readfs))
{//IF INPUT RECEIVED
qDebug("************RECEIVED DATA****************");
FlushBuf();
qDebug("\nReading data into a read buffer");
int bytes_read=mPort->ReadPort(mBuf,1000);
mFrameReceived=false;
for(int i=0;i<bytes_read;i++)
{
qDebug("%x",mBuf[i]);
}
//if complete frame has been received, write the acknowledge message frame to the port.
if(bytes_read>0)
{
qDebug("\nAbout to Process Received bytes");
ProcessReceivedBytes(mBuf,bytes_read);
qDebug("\n Processed Received bytes");
if(mFrameReceived)
{
int no_bytes=mPort->WritePort(mAcknowledgeMessage,ACKNOWLEDGE_FRAME_SIZE);
}//if frame received
}//if bytes read > 0
} //if input received
}//end while
}
The problem is when I exit from this thread, using
delete <protocolclass>::instance();
the program crashes with a glibc error of malloc memory corruption. On checking the core with gdb it was found the when exiting the thread it was processing the data and thus the error. The destructor of the protocol class looks as follows:
<ProtocolClass>::~<ProtocolClass>()
{
delete [] mpTrackInfo; //delete data
wait();
mPort->ClosePort();
s_instance = NULL; //static instance of singleton
delete mPort;
}
Is this due to select? Do the semantics for destroying objects change when select is involved? Can someone suggest a clean way to destroy threads involving select call.
Thanks
I'm not sure what threading library you use, but you should probably signal the thread in one way or another that it should exit, rather than killing it.
The most simple way would be to keep a boolean that is set true when the thread should exit, and use a timeout on the select() call to check it periodically.
ProtocolClass::StopThread ()
{
kill_me = true;
// Wait for thread to die
Join();
}
ProtocolClass::run ()
{
struct timeval tv;
...
while (!kill_me) {
...
tv.tv_sec = 1;
tv.tv_usec = 0;
res = select (maxfd, &readfds, NULL, NULL, &tv);
if (res < 0) {
// Handle error
}
else if (res != 0) {
...
}
}
You could also set up a pipe and include it in readfds, and then just write something to it from another thread. That would avoid waking up every second and bring down the thread without delay.
Also, you should of course never use a boolean variable like that without some kind of lock, ...
Are the threads still looking at mpTrackInfo after you delete it?
Not seeing the code it is hard.
But Iwould think that the first thing the destructor should do is wait for any threads to die (preferably with some form of join() to make sure they are all accounted for). Once they are dead you can start cleaning up the data.
your thread is more than just memory with some members, so just deleting and counting on the destructor is not enough. Since I don't know qt threads I think this link can put you on your way:
trolltech message
Two possible problems:
What is mpTrackInfo? You delete it before you wait for the thread to exit. Does the thread use this data somewhere, maybe even after it's been deleted?
How does the thread know it's supposed to exit? The loop in run() seems to run forever, which should cause wait() in the destructor to wait forever.