2013-04-17 | 17:07
排他制御を考慮していない並列処理
次のプログラムは、Workerクラスのdo_something()内で"*"を10個印字した後、改行している。ただし、別なスレッドが"+"を印字するinterrupt()を呼び出しているため、"*"と"+"が混じってしまう。
#include <iostream>
#include <boost/thread.hpp>
class Worker{
public:
void do_something(){
while(true){
for(int i = 0 ; i < 10 ; i++){
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
std::cout << "*" ;
}
std::cout << std::endl;
}
}
void interrupt(){
std::cout << "+";
}
private:
};
int main(){
Worker w;
boost::thread_group g;
g.create_thread([&w](){
while(true){
boost::this_thread::sleep(boost::posix_time::milliseconds(40));
w.interrupt();
}
});
w.do_something();
g.join_all();
std::cout << "bye" << std::endl;
return 0;
}
改良
io_serviceをメンバに追加し、interrupt()では印字処理をio_serviceにpost()し、do_something()のループ内でio_service::run()を呼び出す。これにより、"+"を印字する処理は"*"の印字が終了した後で呼び出されるようになるので、出力が混じることがなくなる。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
class Worker{
public:
void do_something(){
while(true){
for(int i = 0 ; i < 10 ; i++){
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
std::cout << "*" ;
}
std::cout << std::endl;
io_service_.reset();
io_service_.run();
}
}
void interrupt(){
io_service_.post([](){
std::cout << "+";
});
}
private:
boost::asio::io_service io_service_;
};
int main(){
Worker w;
boost::thread_group g;
g.create_thread([&w](){
while(true){
boost::this_thread::sleep(boost::posix_time::milliseconds(40));
w.interrupt();
}
});
w.do_something();
g.join_all();
std::cout << "bye" << std::endl;
return 0;
}
スポンサーサイト
Comment
このコメントは管理者の承認待ちです
このコメントは管理者の承認待ちです
このコメントは管理者の承認待ちです
このコメントは管理者の承認待ちです
Post a comment