Search code examples
c++multithreadingvariadic-functions

Using passed argument list in a function


I'm trying to build a Thread Manager system in C++, which I give commands to, and if there is a thread available, it starts working. I made a template, because i don't assume how a function should look like that gets passed to the system, and because I want it to work on functions in general.

The whole concepts is theoretical for me. My idea is:

  • It gets the function
  • If a thread is available, it runs it
  • If it's finished, it detaches the thread

So I could keep track of how many threads are being used.

template <typename _Ty> void ThreadManager::Run(_Ty T, ...) //T should be a function
{
    using namespace std::literals::chrono_literals;
    while (!is_free_thread_available())std::this_thread::sleep_for(1ms);

    va_list args;
    va_start(args, T);

    auto F = void[=]() {
        std::this_thread::sleep_for(1ms); //to make sure the thread will be added to the vector
        T(args); //i assume this should not work
        for (int i = 0; i < Threads.size(); i++)     //Threads = std::vector<std::thread>
            auto& t = Threads[i];
            if (std::this_thread::get_id() == t.get_id())
            {
                Threads.erase(Threads.begin() + i); t.detach(),  break; //not sure if detaching the active thread works
            }
    }

    std::thread Thread(F);
    Threads.push_back(Thread);

}

This code doesn't run. It returns an unresolved external symbol. I might need a little help with making it run


Solution

  • As you use C++, avoid C-ellipsis and use variadic template:

    That would fix your compilation issue:

    template <typename Func, typename ... Args>
    void ThreadManager::Run(Func func, Args... args)
    {
        using namespace std::literals::chrono_literals;
    
        while (!is_free_thread_available()) std::this_thread::sleep_for(1ms);
    
        auto F = void[=]() {
            func(args...);
    
            // TODO: Synchronization needed to avoid race condition
            for (int i = 0; i < Threads.size(); i++)     //Threads = std::vector<std::thread>
                auto& t = Threads[i];
                if (std::this_thread::get_id() == t.get_id())
                {
                    Threads.erase(Threads.begin() + i);
                    break;
                }
        }
        // TODO: Synchronization needed to avoid race condition
        Threads.emplace_back(F);
    }
    

    Notice that you have also to fix your synchronizations issues