筆者は世に出すサンプルコードのことを甘く見ているので、こんなコードではダメだということに気づかれた方は、お手数でもコメントにお書きください。よろしくお願いいたします。
Visual Studio 2013 は中途半端にC++11が実装されており、スレッドまわりの全ての機能を使うことができない。
そこで、 Poco::Thread
を使おうと考えた。
今回は、stlの std::vector
で複数のPoco::Thread
を管理する。例えば、Poco::Thread
を複数作ることを許容し、その上限数を管理しする場合に使える。
#include <iostream>
#include <vector>
#include <Poco/Thread.h>
#include <Poco/Runnable.h>
#include <Poco/ErrorHandler.h>
class HeavyWorker : public Poco::Runnable
{
public:
int i;
private:
void run()
{
Sleep(1000);
std::cout << "おわった id=" << i << std::endl;
}
};
class MyHandler : public Poco::ErrorHandler {
public:
virtual void exception(const Poco::Exception& exc) {
std::cout << "Poco Exception: " << exc.displayText() << std::endl;
}
virtual void exception(const std::exception& exc) {
std::cout << "std::exception: " << exc.what() << std::endl;
}
virtual void exception() {
std::cout << "Other exception" << std::endl;
}
};
int main() {
MyHandler handler;
Poco::ErrorHandler::set(&handler);
std::vector<Poco::Thread*> vthread;
std::vector<HeavyWorker*> vworker;
int maxNumThread = 4;
for (int i = 0; i < 20; i++) {
while (true) {
if (vthread.size() < maxNumThread) { break; }
for (int i = 0; i < vthread.size(); i++) {
if (vthread[i]->tryJoin(1)) {
delete vworker[i];
vworker.erase(vworker.begin() + i);
delete vthread[i];
vthread.erase(vthread.begin() + i);
i--;
}
}
}
std::cout << "現在のスレッド数" << vthread.size() << std::endl;
Poco::Thread *thread = new Poco::Thread();
HeavyWorker *worker = new HeavyWorker();
worker->i = i;
vworker.emplace_back(worker);
thread->start(*worker);
vthread.emplace_back(thread);
Sleep(100);
}
for (int i = 0; i < vthread.size(); i++) {
vthread[i]->join();
delete vworker[i];
vworker.erase(vworker.begin() + i);
delete vthread[i];
vthread.erase(vthread.begin() + i);
i--;
std::cout << "現在のスレッド数" << vthread.size() << std::endl;
}
return 0;
}
出力例
現在のスレッド数0
現在のスレッド数1
現在のスレッド数2
現在のスレッド数3
おわった id=0
現在のスレッド数3
おわった id=1
現在のスレッド数3
おわった id=2
現在のスレッド数3
おわった id=3
現在のスレッド数3
おわった id=4
現在のスレッド数3
おわった id=5
現在のスレッド数3
おわった id=6
現在のスレッド数3
おわった id=7
現在のスレッド数3
おわった id=8
現在のスレッド数3
おわった id=9
現在のスレッド数3
おわった id=10
現在のスレッド数3
おわった id=11
現在のスレッド数3
おわった id=12
現在のスレッド数3
おわった id=13
現在のスレッド数3
おわった id=14
現在のスレッド数3
おわった id=15
現在のスレッド数3
おわった id=16
現在のスレッド数3
おわった id=17
現在のスレッド数2
おわった id=18
現在のスレッド数1
おわった id=19
現在のスレッド数0
参照
Class Poco::Thread
http://www.digi-con.co.jp/tech/node/180
POCO::Foundationでデザインパターン - マルチスレッド編 - (1/3):CodeZine(コードジン)