網站首頁 編程語言 正文
一、說明
boost::thread的六種使用方法總結,本文初步介紹線程的函數、構造、執行的詳細解釋。
二、boost::thread的幾個函數
函數 | 功能 |
---|---|
join() | 讓主進程等待子線程執行完畢后再繼續執行 |
get_id() | 獲得線程的 id 號 |
detach() | 標線程就成為了守護線程,駐留后臺運行 |
bool joinable() | 是否已經啟動,為 join() |
thread::join()是個簡單暴力的方法,主線程等待子進程期間什么都不能做,一般情形是主線程創建thread object后做自己的工作而不是簡單停留在join上。
thread::join()還會清理子線程相關的內存空間,此后thread object將不再和這個子線程相關了,即thread object不再joinable了,所以join對于一個子線程來說只可以被調用一次,為了實現更精細的線程等待機制,可以使用條件變量等機制。
1、可會合(joinable):這種關系下,主線程需要明確執行等待操作,在子線程結束后,主線程的等待操作執行完畢,子線程和主線程會合,這時主線程繼續執行等待操作之后的下一步操作。主線程必須會合可會合的子線程。在主線程的線程函數內部調用子線程對象的wait函數實現,即使子線程能夠在主線程之前執行完畢,進入終止態,也必須執行會合操作,否則,系統永遠不會主動銷毀線程,分配給該線程的系統資源也永遠不會釋放。
2、相分離(detached):表示子線程無需和主線程會合,也就是相分離的,這種情況下,子線程一旦進入終止狀態,這種方式常用在線程數較多的情況下,有時讓主線程逐個等待子線程結束,或者讓主線程安排每個子線程結束的等待順序,是很困難或不可能的,所以在并發子線程較多的情況下,這種方式也會經常使用。
三、構造
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;
}
執行結果:
第二種情況:類重載operator()構成的函數創建線程
#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;
}
運算結果:
第三種情況:在類內部對static函數創建線程
#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方法。因為static方法要比main方法提前加載,所以static方法不能調用一般方法,進一步說,static方法無法調用比它晚加載的方法,切記。 調用時用HelloWorld::start(),說明start在定義類的時候就已經ready,無需在實例化后再調用。
第四種情況:使用boost::bind函數創建線程
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <boost/function.hpp>
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::function<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;
}
1)定義函數指針 boost::function0< void> f
2)該指針與HelloWorld::hello函數綁定, boost::bind(&HelloWorld::hello, this);
3)線程與函數指針綁定 boost::thread thrd(f);
4)按照常規,將對象實例化后,調用類函數。
運算結果:
第五種情況:在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;
}
線程如何帶參數定義?本例就是參考方法!
原文鏈接:https://yamagota.blog.csdn.net/article/details/127892727
相關推薦
- 2022-05-17 獲取當前機器注冊到nacos上的機器ip
- 2023-07-24 uniapp開發 h5和小程序 拖動懸浮按鈕
- 2022-08-03 在C++中把字符串轉換為整數的兩種簡單方法_C 語言
- 2022-08-05 Redis實現分布式鎖的五種方法詳解_Redis
- 2022-04-07 Redis數據庫分布式設計方案介紹_Redis
- 2023-01-02 最新C語言中getchar的使用_C 語言
- 2022-06-12 C語言實題講解快速掌握單鏈表上_C 語言
- 2022-07-24 C++算法學習之分支限界法的應用_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支