我正在嘗試創建一個具有與 std::thread 類似功能的作業系統,您可以在其中傳遞 lambda 中的引數,這些引數會被捕獲,例如 ( std::thread([&](int index){...} ), 5))
這是整個執行緒類
#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;
};
這目前有點作業,但如果我從 for 回圈中傳入一個索引,例如,每個作業的索引將保持為 0 ......
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);
}
uj5u.com熱心網友回復:
你引入了一個非常有趣的問題:-)
m_Job = m_Jobs.front();
m_Jobs.pop_back();
您總是選擇要執行的第一個元素,但洗掉最后一個。結果是,您總是執行第一個元素。我想,這不是你想要的!當您的回圈0首先插入時,看起來 var 存盤不正確,但確實如此。如果您從 10..20 運行回圈,您將始終看到10。
順便說一句:你在沒有鎖定互斥鎖的情況下執行了很多次你的向量。例如:
void Wait() {
while (!m_Jobs.empty() && !m_Stop) {
...
如果你編譯,-fsanitize=thread你會得到一長串警告。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/403033.html
標籤:
上一篇:執行緒和同步佇列
