Я пытался реализовать ThreadPool, но, к сожалению, столкнулся с некоторыми проблемами.
Это то, что у меня уже есть.
//includes ...
void call()
{
std::cout << "Hi i'm thread no " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << "ready " << std::this_thread::get_id() << std::endl;
};
//Implementation is not shown here to reduce code
class WorkQueue {
public:
bool push(std::function<void()> const& value);
void pop();
bool empty();
};
std::condition_variable g_queuecheck;
std::mutex g_lockqueue;
std::atomic<bool> g_notified;
class ThreadPool
{
public:
ThreadPool(int iNoThread) :
m_noThread(iNoThread)
{
g_notified.store(false);
m_threads.resize(iNoThread);
bIsReady.store(false);
for (int i = 0; i < iNoThread; ++i)
m_threads[i] = std::thread(&ThreadPool::run, this);
}
void run()
{
while (!bIsReady || !m_workQueue.empty())
{
std::unique_lock<std::mutex> locker(g_lockqueue);
if (m_workQueue.empty())
{
while (!g_notified) // Used to avoid spurious wakeups
{
g_queuecheck.wait(locker);
}
if(!bIsReady)
g_notified.store(false);
}
m_workQueue.pop();
}
};
void addWork(std::function<void()> func)
{
m_workQueue.push(func);
g_notified.store(true);
g_queuecheck.notify_one();
}
void join()
{
bIsReady.store(true);
g_notified.store(true);
g_queuecheck.notify_all();
for (int i = 0; i < m_noThread; ++i)
m_threads[i].join();
}
~ThreadPool()
{}
WorkQueue m_workQueue;
int m_noThread;
std::vector<std::thread> m_threads;
std::atomic<bool> bIsReady;
};
int _tmain(int argc, _TCHAR* argv[])
{
{
ThreadPool pool(4);
for (int i = 0; i < 8; ++i)
pool.addWork(call); //This work is done sequentially
pool.join();
}
std::cin.ignore();
return 0;
}
Моя проблема в том, что работа выполняется последовательно.
- Как я могу это исправить?
- Что-то еще не так с моим ThreadPool?
- Является ли ожидание лучшей практикой?
WorkQueue::pop
(похоже, нет другого подходящего места). Если это так, обратите внимание, что это происходит, пока удерживается мьютексg_lockqueue
. - person Igor Tandetnik   schedule 05.08.2015g_notified
не является необходимым и, вероятно, является пессимизацией. Вы должны просто проверить наличиеm_workQueue.empty()
. Также я не уверен, что вы пытаетесь сделать сbIsReady
. - person Mike Vine   schedule 05.08.2015