0

I have a reusable class that starts up an infinite thread. this thread can only be killed by calling a stop function that sets a kill switch variable. When looking around, there is quite a bit of argument over volatile vs atomic variables.

The following is my code: program.cpp

int main()
{
ThreadClass threadClass;
    threadClass.Start();
    Sleep(1000);
    threadClass.Stop();
    Sleep(50);
    threaClass.Stop();
}

ThreadClass.h

#pragma once
#include <atomic>
#include <thread>

class::ThreadClass
{
public:
    ThreadClass(void);
    ~ThreadClass(void);
    void Start();
    void Stop();
private:
void myThread();
    std::atomic<bool> runThread;
    std::thread theThread;
};

ThreadClass.cpp

#include "ThreadClass.h"
    ThreadClass::ThreadClass(void)
    {
        runThread = false;
    }

    ThreadClass::~ThreadClass(void)
    {
    }

    void ThreadClass::Start()
    {
        runThread = true;
        the_thread = std::thread(&mythread, this);
    }

    void ThreadClass::Stop()
    {
        if(runThread)
        {
            runThread = false;
            if (the_thread.joinable())
            {
                the_thread.join();
            }
        }
    }

    void ThreadClass::mythread()
    {
        while(runThread)
        {
            //dostuff
            Sleep(100);  //or chrono
        }
    }

The code that i am representing here mirrors an issue that our legacy code had in place. We call the stop function 2 times, which will try to join the thread 2 times. This results in an invalid handle exception. I have coded the Stop() function in order to work around that issue, but my question is why would the the join fail the second time if the thread has completed and joined? Is there a better way programmatically to assume that the thread is valid before trying to join?

Jason
  • 2,147
  • 6
  • 32
  • 40
  • 3
    Aside: you mean `atomic`, not `volatile bool`. See http://stackoverflow.com/q/2484980/1084944 –  Jun 10 '16 at 19:01
  • Also, [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) –  Jun 10 '16 at 19:05
  • I was intentionally creating a simplistic representation of my code. – Jason Jun 10 '16 at 19:16
  • 2
    Make things as simple as possible, but no simpler. –  Jun 10 '16 at 19:22
  • @Jason You oversimplified. Whatever the problem is, it's not obvious that it's in the code you've provided. – Xirema Jun 10 '16 at 20:13
  • @Xirema, this may be the case. I just needed to verify that the new code that implemented with the threading is correct. I will continue to look through the unrelated code to determine what might be the cause of the issue. Thanks for looking at it guys/girls. – Jason Jun 13 '16 at 13:14
  • @Hurkyl - it turns out that the code that is managing the thread ends up calling the Stop function twice. In this case, the second time we try to join(), it fails due to an invalid handle. I am looking in to how to manage that scenario. – Jason Jun 13 '16 at 16:34
  • The runThread variable protects against it – Daniel Jun 13 '16 at 18:02

0 Answers0