我有Java線程的經驗,但想要學習如何在C++ 11中使用它們。我試圖做一個簡單的線程池,線程創建一次,可以要求執行任務。C++ 11線程未加入
#include <thread>
#include <iostream>
#define NUM_THREADS 2
class Worker
{
public:
Worker(): m_running(false), m_hasData(false)
{
};
~Worker() {};
void execute()
{
m_running = true;
while(m_running)
{
if(m_hasData)
{
m_system();
}
m_hasData = false;
}
};
void stop()
{
m_running = false;
};
void setSystem(const std::function<void()>& system)
{
m_system = system;
m_hasData = true;
};
bool isIdle() const
{
return !m_hasData;
};
private:
bool m_running;
std::function<void()> m_system;
bool m_hasData;
};
class ThreadPool
{
public:
ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
m_threads[i] = std::thread(&Worker::execute, &m_workers[i]);
}
};
~ThreadPool()
{
for(int i = 0; i < NUM_THREADS; ++i)
{
std::cout << "Stopping " << i << std::endl;
m_workers[i].stop();
m_threads[i].join();
}
};
void execute(const std::function<void()>& system)
{
// Finds the first non-idle worker - not really great but just for testing
for(int i = 0; i < NUM_THREADS; ++i)
{
if(m_workers[i].isIdle())
{
m_workers[i].setSystem(system);
return;
}
}
};
private:
Worker m_workers[NUM_THREADS];
std::thread m_threads[NUM_THREADS];
};
void print(void* in, void* out)
{
char** in_c = (char**)in;
printf("%s\n", *in_c);
}
int main(int argc, const char * argv[]) {
ThreadPool pool;
const char* test_c = "hello_world";
pool.execute([&]() { print(&test_c, nullptr); });
}
的這個輸出是:
hello_world
Stopping 0
之後,主線程暫停,因爲它在等待第一個線程加入(ThreadPool中的析構函數)。出於某種原因,工作人員的m_running
變量未設置爲false,這會使應用程序無限期地運行。
它在我的電腦上正常工作。用visual studio構建2013 –
@DavidHaim:代碼包含未定義的行爲。代碼的行爲如預期是完全可能的。 Howerver因爲對共享變量m_running的訪問不同步,編譯器可以假定它不會在工作線程中更改。即使編譯器沒有對其進行優化,CPU也可以採取相同的措施,並且從不更新m_running的高速緩存條目,並使用其他CPU或內核中更改後的值更新。所以最終的行爲取決於你的編譯器,它的優化和你的CPU。 – Finn