Im trying to make a job system with a similar feature as std::thread where you can pass in parameters in a lambda which get captured e.g ( std::thread([&](int index){...} ), 5)
)
This is the entire thread class
#include <condition_variable>
#include <functional>
#include <thread>
using uint = unsigned int;
class Thread {
public:
Thread() {
Start();
}
virtual ~Thread() {
Shutdown();
}
void Start() {
m_Thread = std::thread(&Thread::Poll, this);
}
void Poll() {
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Condition.wait(lock, [this]()
{
return !m_Jobs.empty() && !m_Stop;
});
m_Job = m_Jobs.front();
m_Jobs.pop_back();
}
m_Job(); // function<void()> type
}
void Execute(std::function<void()> New_Job) {
{ std::unique_lock<std::mutex> lock(m_Mutex);
m_Jobs.push_back(New_Job);
}
m_Condition.notify_one();
}
template <typename Func, typename... Args>
void ExecuteParams(Func f, Args... args) {
Execute(std::bind(f, args...));
}
void Wait() {
while (!m_Jobs.empty() && !m_Stop) {
Poll();
}
}
void Shutdown() {
{
std::unique_lock<std::mutex> lock(m_Mutex);
m_Stop = true;
}
m_Condition.notify_all();
m_Thread.join();
}
std::thread m_Thread;
std::mutex m_Mutex;
std::condition_variable m_Condition;
bool m_Stop = false;
std::function<void()> m_Job;
std::vector<std::function<void()>> m_Jobs;
};
This currently works sort of but if i pass in an index from a for loop for example, the index will just stay 0 for each job...
for(uint i = 0; i < 5; i ) {
MainThread.ExecuteParams([&](uint test)
{
std::unique_lock<std::mutex> L(lock);
std::cout << "executing on thread " << std::this_thread::get_id() << std::endl;
std::cout << test << std::endl;
}, i);
}
CodePudding user response:
You have a very funny problem introduced :-)
m_Job = m_Jobs.front();
m_Jobs.pop_back();
You always pick the FIRST element to execute, but remove the last one. The result is, that you always execute the first element. I expect, that is not what you want! And as your loop inserts with 0
first, it looks like the var is not stored correctly, but it is. If you run your loop from 10..20 you will always see 10
instead.
BTW: You execute a lot of times your vector without locking the mutex. For example:
void Wait() {
while (!m_Jobs.empty() && !m_Stop) {
...
If you compile with -fsanitize=thread
you get a long list of warnings.