1
2
不愧是C++,多線程果然是煩!
先記下來:
04 |
void worker(const std::string& s) |
06 |
//outside critical section |
08 |
//outside critical section |
09 |
boost::lock_guard<boost::mutex> lock_obj(m_guard); //lock() |
10 |
//inside critical section |
11 |
cout << s << " Enter critical section" << endl; |
12 |
std::cout << s << '\t' |
13 |
<< "Now sleeping...." << endl; |
14 |
boost::this_thread::sleep(boost::posix_time::milliseconds(5000)); |
15 |
cout << s << " Quit critical section" << endl; |
16 |
//inside critical section |
18 |
//outside critical section |
23 |
std::string s1 = "t1 "; |
24 |
std::string s2 = "t2 "; |
26 |
//two ways to initialize a thread |
27 |
boost::thread thr1(worker,s1); |
28 |
boost::thread thr2(Adapter<WorkerFunPtr, std::string>(worker, s2)); |
30 |
//wait thread1 and thread2 to complete their work |
34 |
cout << "All thread end" << endl; |
注意到,這個C++lock的方式還是很特別的;其他語言,比如C#\Java,都是內建了lock關鍵字,以
的形式來表明鎖住 Critical section,而在Boost中是以申明一個lockguard變數(本例中如此,應該還有其他方式)的形式來申明進入Critical section,並且以這個lockguard變數的消亡來退出Critical section。因此要拿捏好這個變數的生存周期。比如以花括弧來控制這個局部變數的生存周期
01 |
//outside critical section |
03 |
//outside critical section |
04 |
boost::lock_guard<boost::mutex> lock_obj(m_guard); //lock() |
05 |
//inside critical section |
06 |
cout << s << " Enter critical section" << endl; |
08 |
cout << s << " Quit critical section" << endl; |
09 |
//inside critical section |
11 |
//outside critical section |
非常精巧
原文地址:http://www.cppblog.com/janvy/archive/2010/03/25/110498.aspx
最近在做一個訊息中介軟體裡面涉及到多線程編程,由於跨平台的原因我採用了boost線程庫。在建立線程時遇到了幾種線程建立方式現總結如下:
首先看看boost::thread的建構函式吧,boost::thread有兩個建構函式:
(1)thread():構造一個表示當前執行線程的線程對象;
(2)explicit thread(const boost::function0<void>& threadfunc):
boost::function0<void>可以簡單看為:一個無返回(返回void),無參數的函數。這裡的函數也可以是類重載operator()構成的函數;該建構函式傳入的是函數對象而並非是函數指標,這樣一個具有一般函數特性的類也能作為參數傳入,在下面有例子。
第一種方式:最簡單方法
#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout <<
"Hello world, I''m a thread!"
<< std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);
thrd.join();
return 0;
}
第二種方式:複雜類型對象作為參數來建立線程:
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
boost::mutex io_mutex;
struct count
{
count(int id) : id(id) { }
void operator()()
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": "
<< i << std::endl;
}
}
int id;
};
int main(int argc, char* argv[])
{
boost::thread thrd1(count(1));
boost::thread thrd2(count(2));
thrd1.join();
thrd2.join();
return 0;
}
第三種方式:在類內部建立線程;
(1)類內部靜態方法啟動線程
#include <boost/thread/thread.hpp>
#include <iostream>
class HelloWorld
{
public:
static void hello()
{
std::cout <<
"Hello world, I''m a thread!"
<< std::endl;
}
static void start()
{
boost::thread thrd( hello );
thrd.join();
}
};
int main(int argc, char* argv[])
{
HelloWorld::start();
return 0;
}
在這裡start()和hello()方法都必須是static方法。
(2)如果要求start()和hello()方法不能是靜態方法則採用下面的方法建立線程:
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
class HelloWorld
{
public:
void hello()
{
std::cout <<
"Hello world, I''m a thread!"
<< std::endl;
}
void start()
{
boost::function0< void> f = boost::bind(&HelloWorld::hello,this);
boost::thread thrd( f );
thrd.join();
}
};
int main(int argc, char* argv[])
{
HelloWorld hello;
hello.start();
return 0;
}
(3)在Singleton模式內部建立線程:
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
class HelloWorld
{
public:
void hello()
{
std::cout <<
"Hello world, I''m a thread!"
<< std::endl;
}
static void start()
{
boost::thread thrd( boost::bind
(&HelloWorld::hello,&HelloWorld::getInstance() ) ) ;
thrd.join();
}
static HelloWorld& getInstance()
{
if ( !instance )
instance = new HelloWorld;
return *instance;
}
private:
HelloWorld(){}
static HelloWorld* instance;
};
HelloWorld* HelloWorld::instance = 0;
int main(int argc, char* argv[])
{
HelloWorld::start();
return 0;
}
第四種方法:用類內建函式在類外部建立線程;
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
class HelloWorld
{
public:
void hello(const std::string& str)
{
std::cout <<str<< std::endl;
}
};
int main(int argc, char* argv[])
{
HelloWorld obj;
boost::thread thrd( boost::bind(&HelloWorld::hello,&obj,"Hello
world, I''m a thread!" ) ) ;
thrd.join();
return 0;
}
如果線程需要綁定的函數有參數則需要使用boost::bind。比如想使用 boost::thread建立一個線程來執行函數:void f(int i),如果這樣寫:boost::thread thrd(f)是不對的,因為thread建構函式聲明接受的是一個沒有參數且傳回型別為void的型別,而且不提供參數i的值f也無法運行,這時就可以寫:boost::thread thrd(boost::bind(f,1))。涉及到有參函數的綁定問題基本上都是boost::thread、boost::function、boost::bind結合起來使用
完