Vex::thread constructor for initialization

Hey everyone, I’m trying my hand at a multithreading program this year and I need some help setting it up. I’ve gone through the motions of std::thread vs vex::thread and I thought I had it but now I’m getting more errors. I’m a bit confused because I set up the first one the same way I set up the ones that are getting errors in the compiler.
Here’s an excerpt of my code:

else if (Controller1.ButtonUp.pressing()){
   vex::thread t2(function(5));
}

The error I get from that is ‘no matching constructor for initialization of vex::thread’.
Here’s another excerpt, but this one has no error.

if (Bumper.pressing() == true && Running == false) {
    Running = true;
    vex::thread t3(otherFunction);
}

I have no idea what’s going on.

Threads a bit complicated…
Also my answer is based of how std::thread works. VEXcode’s implementation might be slightly different.

vex::thread myThreadName(myFunctionName);

Your first misstake is you put function(5), this runs the function and you do not want to do that. Instead just put function.

Also you have Controller1.ButtonUp.pressing() which would run the whole time you hold the button and cause many threads to be created.


Then variables get deallocated when they go out of scope. What this means…

{
    vex::thread t2(function);
}

The { } are a scope and when the program reaches the } all variables declared in this scope are deallocated (t2), unless they are pointers.

The thing with thread is that when it is deallocated, if it is joinable the program will terminate.
What is joinable

When you declare a thread it starts running. You can now call .join() which will wait for the thread to finish, at this point it will be: not joinable. You can also call .detach(). This will make the thread run and not be associated with the variable. It will also cause the thread to be: not joinable. Note that even when the thread finishes running it will still be joinable.


Thread Vs Task, what is the difference…

Like the standard std::thread implementation, threads cannot be stop through the variable. To stop a thread it must end it’s self. For this reason VEXcode has a task class, which does the same thing, but has functions like: .stop(), .suspend(), .resume() to give you that sort of control of stop or pausing the thread. However, vex::task doesn’t have .join() or .detach().


So what are the Solutions to implement this the way you want? It depends on how you want it to function.

The simplest is to have a thread the runs another loop, and is started at the beginning of the program. This is just creating a global thread variable, or you can put it in main since the program ends anyway when main ends (As you may remember when main is ready to end, the thread variable will get deallocated, but since it is still joinable it will terminate the program, but it doesn’t matter because main is done anyway).

vex::thread myThreadName(myFunctionName);

If you want to have a macro that runs a thread, there are options on how you can do it. First decide: do you want the previous thread to stop when you click the macro again and the previous thread isn’t done yet, or do you want to not allow the macro to work while the thread is running, and do you want to have a button to the thread…

Thread has no way of checking if the task is done, so you would need to communicating between threads. Then vex::thread has no way of stop a task (unless you communicate between tasks), but vex::task has very simple function stop or pause the thread.

The simplest way to run a thread from an if statement or somewhere that goes out of scope…

vex::thread(myFunctionName).detach();

You could do stuff like this…

vex::thread *myThreadName;

int main()
{
    //myThreadName is not running

    {
        myThreadName = new std::thread(myFunctionName);
    }

    //myThreadName is still running
}

The new std::thread(myFunctionName) creates a thread, but as a pointer so it never get deallocated. It doesn’t even need to be saved in a variable, but you really should dellocated it when your done, otherwise it will just take up a small piece of memory.


In Conclusion it is complicated, but you really should learn it.

5 Likes

Hm, it’s really not that complicated.
I’ll post some more details later, but a vex::thread is not a std::thread so many of the issues associated with a std::thread don’t really apply.

2 Likes

Yes the answer is based on std::thread. An in-depth explanation on how vex::thread works would be great.

First, thank you @Codec for such an in-depth response, I really wasn’t able to find much info on vex::thread so this has been a huge help.
I did make sure the thread would only be created once, I just didn’t show a large enough excerpt of my code.
I didn’t think about function(5) running the function, that’s a good catch. Do I have to specify input inside the function itself then?