Boost也提供了跨平台的多執行緒函式庫,該有的都有(R/W mutex還有問題,還沒正式納入),不過跟普通的多執行緒函式庫有點不同
1. 啟動方法
使用pthread的programmer會用以下方法啟動一個 thread
pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
start_routine就是thread的進入點,arg是要傳入的參數,因為只能傳一個參數,所以我們通常都是把所有參數擠在一個struct裡面......
Boost Thread是在建立thread物件時啟動一個執行緒的
boost::thread *mythread = new boost::thread(&threadfunc);
跟 一般不同的是,Boost Thread是接受Boost Function來當作thread的進入點,而不是一般的function pointer而已,上面範例的function pointer只是Boost Function的其中一種type而已, 所以, 我們可以輕鬆做到以下這種事:
struct MyClass
{
void threadfunc() {// do something}
};
int main()
{
MyClass m;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread...
}
直 接把non-static member function當成thread的進入點!!在以前pthread的時代,想要跑non-static member function非常麻煩,通常要寫個static wrapper之類的......拜Boost Function和Boost Bind之賜,這兩者與Boost Thread的完美結合,讓C++ programmer的生活更輕鬆了!!
有人可能已經發現了,Boost Thread在創造thread的時候,沒有地方可以傳參數進去阿!!Well,有了Boost Bind,這根本就不是問題,還能做的比以前更好。
struct MyClass
{
void threadfunc(int a, double b) {}
};
int main()
{
MyClass m;
boost::thread mythread(
boost::bind(&MyClass::threadfunc, &m, 1, 2.2));
// Wait for the thread
}
不像以前只能傳void*參數,使用bind想要傳幾個都可以,而且還是type-safe的方式。不過,既然都可以bind member function了,把參數當作member variable的寫法可能比較好
struct MyClass
{
void threadfunc() {}
int m_a;
double m_b;
};
int main()
{
MyClass m;
m.m_a = 1;
m.m_b = 2.2;
boost::thread mythread(boost::bind(&MyClass::threadfunc, &m));
// Wait for the thread
}
2. Mutex的概念
以前在pthread我們都會這樣來使用mutex
// declare mutex
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
void threadfunc(void* param)
pthread_mutex_lock(&m);
// Only one can enter here...
pthread_mutex_unlock(&m);
}
Boost Thread則是把lock當成一個物件,建構出來時表示鎖住一個mutex,解構表示解鎖一個mutex。
// declare mutex
boost::mutex m;
void threadfunc()
boost::mutex::scoped_lock lock(m);
// On exiting this function, the mutex is unlocked
}
由 於lock是stack-allocated的物件,所以在function結束後,lock會自動被摧毀,mutex就會處於unlocked狀態。 Boost Thread的lock都不保證thread-safe,其實它最好應該都被使用在stack裡,thread之間只要share mutex就可以了。
int threadfunc()
{
{
// The first critical section
boost::mutex::scoped_lock lock(m);
// do something
}
{
// The second critical section
boost::mutex::scoped_lock lock(m);
//do something
}
}
把critical section用括號包起來,然後在最前面創造一個lock,這樣就可以保證這個block的thread-safe了,這樣的寫法比較直覺而且簡潔多了,不會再像以前一樣忘記unlock mutex......
Boost Thread也有一些不足,例如沒有r/w mutex和thread termination。在很多thread lib裡,thread termination通常會牽涉到thread-safe的問題,所以大多數都會有個warning提醒programmer最好不要使用thread termination以避免發生問題(例如memory leak)。事實上,thread termination最好自己在thread裡面implement,才是最保險的作法。
1 則留言:
感恩 寫得簡單易懂
It helps a lot.
張貼留言