[boost]boost::thread
Posted 2009/01/30 15:48|
|
|
댓글 하나가 운영자에겐 커다란 힘이 됩니다!
- 쓰레드함수가 외부에 있을때 ( func1 은 void형 )
: boost::thread threadVar1( &func1 );
- 쓰레드함수가 클래스의 멤버 평선일때
: boost::thread threadVar2( boost::bind(&ClassName::func2, this) );
boost::bind는 함수의 인자의 갯수변화를 줄때 쓰이는데, 여기서 thread 생성시 필요한 함수는 인자가 void여야 한다. 우리가 맴버함수안에서 "인자가 void인 다른 맴버함수"를 부를때는 선언한 형식대로 선언해주면 된다고 생각하고 있는데, 모든 맴버함수는 가장 첫번째 인자 this 를 생략하고 있음을 명심해야 한다. 즉 void TestClass(int t1, int t2)는 원래 TestClass(this, 3, 4) 형태로 불리워야 한다는 것이다.
----------------------------------------------------------------------------------
- Thread를 제어하는 2가지: Mutex 와 condition
- Mutex : 운영체제에서 익히나온 것이다. Thread 가 동시다발적으로 어느 특정 리소스를 사용할때, 한개의 Thread만 사용하게 하고싶을때 사용하는 녀석이다. 제대로 사용하지 않으면 성능저하를 일으키니 디자인설계때부터 조심히 사용해야 하는 녀석이다. 추천하는
- header : #include <boost/thread/mutex.hpp>
- 추천하는 것 : boost::mutex::scoped_lock
- 이유 : 사용하기 편하다. 이 변수를 괄호 안에 선언하게 되면 괄호의 끝을 만날때까지 잠금이 되고, 괄호를 벗어나게되면 락이 풀린다. (이에 대한 원리는 간단히 생각해보면 되는데, 생성자에서 락을 걸고, 소멸자에서 락을 푸는 코드를 삽입한 것이다)
boost::mutex mutexVar; // Lock을 걸 mutex 변수
if ( test_module == true )
{
boost::mutex::scoped_lock( mutexVar ); // Mutex Lock이 걸림
// Do something
} // 이 시점에서 락이 풀린다.
- condition : 쓰레드를 잠들게 하고 동작하게 하는 제어 변수. 보통 어떤 값을 기다릴때 while 로 돌리는 방법이나 sleep 을 줘서 일정시간마다 체크하는 경우가 있는데 이는 대부분 비효율적이며, 데이터가 아직 완성이 안되어있으면 잠들어있다가 완료시점에 신호를 보내어 깨어나게 한다. 기억해야 할 점은, 만약 집단의 쓰레드들을 관리해서 경쟁적으로 한개씩 깨어나게 하고 싶다면 하나의 condition 변수를 쓰레드들 사이에서 공유해야 한다.
void threadFunction(void)
{
while( true )
{
boost::mutex::scoped_lock lock( mutexVar );
// Thread 초기화 작업
condition.wait(mutexVar); // 현재 실행중인 Thread는 대기모드로
// 들어가고 mutexVar로 걸린 락이 해지
// 된다.// 외부 코드에서 깨우고 싶을때..
condition.notify_one(); // 잠들어있는 것중에서 경쟁적으로 한개만 깨울때
condition.notify_all(); // 잠들어있는 모든 녀석을 깨울때
Error Message
- /usr/local/include/boost-1_36/boost/thread/pthread/condition_variable.hpp:71: boost::condition_variable_any::~condition_variable_any(): Assertion `!pthread_mutex_destroy(&internal_mutex)' failed.
원인 : 생성한 Thread 들은 condition.wait() 을 하고 있는데 프로세스가 죽은 경우 이런 메시지가 나온다.
해결 : 프로세스 종료 루틴에서 모든 쓰레드를 join 시킨후(또는 모두 종료시킨후) 종료하게 한다.
class CKsc{
public:
void f( int i, int j, void* pVoid ){...}
void start();
private:
boost::thread* thread_;
};
void CKsc::start()
{
thread_ = new boost::thread( boost::bind(&CKsc::f, this, 1, 2, this ));
}
생성과 동시에 thread 함수인 f가 돌기 시작한다.
두번째 매개 변수는 첫번째로 넘긴 CKsc::f의 대상 객체가 된다. 위의 예제에서는 CKsc객체 내에서 호출을 하기 때문에 this가 가능한것이다. 외부에서 할 경우에는
CKsc a;
boost::thread* thread_ = new boost::thread( boost::bind(&CKsc::f, a, 1, 2, this ));
혹은
boost::thread* thread_ = new boost::thread( boost::bind(&CKsc::f, &a, 1, 2, this ));
boost는 쓰레드 함수 지정시 이미 쓰레드는 자동으로 수행된다는 점이다
이렇게 하면 된다.
첫번째 처럼 하면 a가 복사되어 넘어가게 되는것이고, 두번째 예제처럼 하면 포인터가 넘어가서 공유가 된다.
void hello(const char* s)
...
int main() {
thread t( bind(&hello, ",world") );
}
위의 정보가 도움이 되셨나요? 그렇다면 댓글 하나만 남겨주세요.
댓글 하나가 운영자에겐 커다란 힘이 됩니다!
- Filed under : 프로그래밍/C & Cpp
- 1 Comment Trackback


최익필
| 2009/09/28 11:54 | PERMALINK | EDIT | REPLY |잘 보고 갑니다. : )