スレッドのメイン関数をメンバ関数にしたい!
たまに使って、そのたびに忘れてしまうのでメモです。
スレッドのメイン関数をクラスのメンバ関数として定義したい場合があります。
ですが、一般にスレッドのエントリ関数はstaticな関数を要求されます。
そこで、
- staticな関数を用意し、そこにインスタンスを渡してから実行する(A)
- bindなのでメンバ関数をstaticとして扱えるようにする(B)
この2種類の方法を考えました。
(もっと良い方法があれば教えて下さい)
試したスレッドライブラリは
- boost::thread
- pthread
です。
c++11のスレッドは試していません。がboost::threadと同じようになってくれることを期待したいです。
結果
ざっくり表にまとめると以下のような感じです。
boost::threadはA,Bどちらも上手くいきました。
pthreadは少し面倒でどうしても関数ポインタを引数に求めるので、上手くbindとかで渡せませんでした。
スレッドライブラリ | A | B |
---|---|---|
pthread | OK | NG |
boost::thread | OK | OK |
OK:メンバ関数をスレッドのメインとしてから呼び出せた | ||
NG:できなかった |
書いたコード
pthreadでA方式
LaunchMemberFunctionというstaticな関数を定義して
reinterpret_castでインスタンスからメンバ関数呼び出しを行なって
実現しています。
pthread.cpp
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <functional>
using namespace std;
class MyClass {
public:
void function() {
std::cout << "Hello,World" << std::endl;
return;
};
};
void* LaunchMemberFunction(void *obj)
{
MyClass *myClass = reinterpret_cast<MyClass *>(obj);
myClass->function();
return NULL;
}
int main() {
MyClass myObj;
pthread_t thr;
pthread_create(&thr, NULL, LaunchMemberFunction, &myObj);
pthread_join(thr,NULL);
}
boostでB方式
boost::bindなどを駆使してメンバ関数をスレッドに渡してあげると
動作しました。
boost.cpp
// boost-thread.cpp
// boost::threadを使う場合
#include <iostream>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
using namespace std;
using namespace boost;
// メンバ関数をマルチスレッドで実行
class MyClass {
public:
void run() {
cout << "hello,world" << endl;
}
};
int main() {
MyClass myClass;
thread thr_main(bind(&MyClass::run, &myClass));
thr_main.join();
return 0;
}