中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站版面布局結(jié)構(gòu)武漢百度百科

網(wǎng)站版面布局結(jié)構(gòu),武漢百度百科,在線培訓(xùn)app,制作一個(gè)html網(wǎng)頁(yè)1 線程基本管控 每個(gè)C程序都含有至少一個(gè)線程,即運(yùn)行main()的線程,它由C運(yùn)行時(shí)系統(tǒng)啟動(dòng)。隨后程序可以發(fā)起更多線程,它們以別的函數(shù)作為入口。這些新線程連同起始線程并發(fā)運(yùn)行。當(dāng)main()返回時(shí),程序就會(huì)退出;同樣&…

1 線程基本管控

每個(gè)C++程序都含有至少一個(gè)線程,即運(yùn)行main()的線程,它由C++運(yùn)行時(shí)系統(tǒng)啟動(dòng)。隨后程序可以發(fā)起更多線程,它們以別的函數(shù)作為入口。這些新線程連同起始線程并發(fā)運(yùn)行。當(dāng)main()返回時(shí),程序就會(huì)退出;同樣,當(dāng)入口函數(shù)返回時(shí),對(duì)應(yīng)的線程隨之終結(jié)。如果借std::thread對(duì)象管控線程,即可選擇等他結(jié)束。

1.1 發(fā)起線程

線程通過(guò)構(gòu)造std::thread對(duì)象而啟動(dòng),該對(duì)象指明線程要運(yùn)行的任務(wù)。

void do_some_work();
std::thread myThread(do_some_work);

任何可調(diào)用類型都適用于std::thread。所以,作為代替,可以設(shè)計(jì)一個(gè)帶有函數(shù)調(diào)用操作符的類(應(yīng)當(dāng)是下面的operator)

class background_task
{
public:void operator() () const{do_something();do_something_else();}
};background_task f;
std::thread my_thread(f);

f被復(fù)制到屬于新線程的存儲(chǔ)空間中,在那里被調(diào)用,由新線程執(zhí)行。

1.1.1 與函數(shù)聲明進(jìn)行區(qū)分

如果傳入std::thread的是臨時(shí)變量,不是具名變量,那么調(diào)用構(gòu)造函數(shù)的語(yǔ)法有可能與函數(shù)聲明相同。這種情況,編譯器會(huì)將其解釋成函數(shù)聲明。

聲明為函數(shù):函數(shù)名為my_thread,只接收一個(gè)參數(shù),返回std::thread對(duì)象
std::thread my_thread(background_task());可以通過(guò)多用一對(duì)圓括號(hào)或使用新式的統(tǒng)一初始化語(yǔ)法
std::thread my_thread((background_task()));
std::thread my_thread{background_task()};還可以使用lambda表達(dá)式
std::thread my_thread([]{do_something();do_something_else();
});

1.2 匯合與分離

在啟動(dòng)線程后,需要明確是要等待他結(jié)束(也就是匯合)還是任由他獨(dú)立運(yùn)行(也就是分離)。如果等到std::thread銷毀的時(shí)候還沒(méi)有決定好,那么std::thread的析構(gòu)函數(shù)將調(diào)用std::terminate()終止整個(gè)程序。

如果選擇了分離,且分離時(shí)新線程還未運(yùn)行結(jié)束,那將繼續(xù)運(yùn)行,甚至在std::thread對(duì)象銷毀很久之后依然運(yùn)行,它只有最終從線程函數(shù)返回時(shí)才會(huì)結(jié)束運(yùn)行。

假設(shè)程序不等待線程結(jié)束,那么在線程運(yùn)行結(jié)束前,我們要保證它所訪問(wèn)的外部數(shù)據(jù)始終正確,有效。由于使用多線程,所以我們可能會(huì)經(jīng)常面臨對(duì)象生存期的問(wèn)題。比如下面的案例:

struct func
{int& i;func(int& i_):i(i_){}void operator() (){for (unsigned j=0; j<1000000; ++j) {do_something(i);    隱患:可能訪問(wèn)懸空引用}}
};void oops()
{int some_local_state=0;func my_func(some_local_state);std::thread my_thread(my_func);my_thread.detach();        不等待新線程結(jié)束新線程可能仍運(yùn)行,而主線程的函數(shù)卻已經(jīng)結(jié)束
}

主線程新線程
構(gòu)造my_func對(duì)象,引用局部變量some_local_state
通過(guò)my_thread對(duì)象啟動(dòng)新線程
新線程啟動(dòng)
調(diào)用func::operator()
分離新線程my_thread

運(yùn)行func::operator();

調(diào)用do_something()函數(shù),

進(jìn)而引用局部變量some_local_state

銷毀局部變量some_local_state

仍在運(yùn)行

退出oops()

繼續(xù)運(yùn)行func::operator();

調(diào)用do_something()函數(shù),

進(jìn)而引用some_local_state,

導(dǎo)致未定義行為

因此:以下做法不可取:意圖在函數(shù)中創(chuàng)建線程,并讓線程訪問(wèn)函數(shù)的局部變量。除非線程肯定會(huì)在該函數(shù)退出前結(jié)束。或者是匯合新線程,此舉可以保證在主線程的函數(shù)退出前,新線程執(zhí)行完畢。

1.2.1 join—等待線程完成

若需等待線程完成,那么可以在與之關(guān)聯(lián)的std::thread實(shí)例上,通過(guò)調(diào)用成員函數(shù)join()實(shí)現(xiàn)。對(duì)于上面的代碼,就是把detach換成join。就能夠保證在oops退出前,新線程結(jié)束。

對(duì)于一個(gè)線程,join僅能被調(diào)用一次,被調(diào)用后線程不再可匯合,成員函數(shù)joinable將返回false。

要注意,如果線程啟動(dòng)后有異常拋出,而join尚未執(zhí)行,該join調(diào)用會(huì)被略過(guò)

使用thread_guard保證在拋出異常時(shí),退出路徑的先后順序與不拋出異常時(shí)一致。

也就是在析構(gòu)函數(shù)中調(diào)用join

class thread_guard {std::thread& t;
public:explicit thread_guard(std::thread& t_) : t(t_){}~thread_guard() {if (t.joinable()) {t.join();}}thread_guard(thread_guard const&)=delete;thread_guard& operator=(thread_guard const&)=delete;
};struct func {int& i;explicit func(int& i_) : i(i_) {};void operator() () {for (unsigned j = 0; j < 1000000; ++j) {do_somthing();}}
};void f() {int some_local_state=0;func my_func(some_local_state);std::thread t(my_func);thread_guard g(t);do_something_in_current_thread();
}

1.2.2 detach—在后臺(tái)運(yùn)行線程

會(huì)令線程在后臺(tái)運(yùn)行,因此與之無(wú)法直接通信。其歸屬權(quán)和控制權(quán)都交給了C++運(yùn)行時(shí)庫(kù),由此保證,一旦線程退出,與之關(guān)聯(lián)的資源都會(huì)被正確回收。

只有在joinable返回true時(shí),才能調(diào)用detach。

2 向線程函數(shù)傳遞參數(shù)

直接向std::thread的構(gòu)造函數(shù)增添更多參數(shù)即可。需要注意的是,線程具有內(nèi)部存儲(chǔ)空間,參數(shù)會(huì)按照默認(rèn)方式先復(fù)制到該處,新創(chuàng)建的執(zhí)行線程才能直接訪問(wèn)它們。然后,這些副本被當(dāng)成臨時(shí)變量,以右值的形式傳給新線程上的函數(shù)或可調(diào)用對(duì)象。即便函數(shù)相關(guān)參數(shù)按設(shè)想應(yīng)該是引用,上述過(guò)程依然會(huì)發(fā)生。

void f(int i, std::string const& s);
std::thread t(f, 3, "hello");void f(int i, std::string const& s);
void oops(int some_param)
{char buffer[1024];sprintf(buffer, "%i", some_param);std::thread t(f, 3, buffer);// std::thread t(f, 3, std::string(buffer));t.detach();
}

但是上述例子將字符串的引用復(fù)制到了thread的存儲(chǔ)空間,當(dāng)調(diào)用thread的外層函數(shù)銷毀時(shí),buffer將不存在,無(wú)法訪問(wèn)這個(gè)引用。可以使用注釋里的方法,先轉(zhuǎn)換成std::string對(duì)象(buffer相當(dāng)于一個(gè)指針)

void update_data_for_widget(widget_id w, widget_data& data);
void oops_again(widget_id w)
{widget_data data;std::thread t(update_data_for_widget, w, data);display_status();t.join();process_widget_data(data);
}

根據(jù)update_data_for_widget函數(shù)的聲明,第二個(gè)參數(shù)會(huì)以引用的方式傳入update_data_for_widget,但是std::thread的構(gòu)造函數(shù)并不知情,會(huì)直接復(fù)制提供的值。隨后線程庫(kù)內(nèi)部會(huì)把參數(shù)副本當(dāng)成move-only(只移型別),以右值的形式傳遞。最終,update_data_for_widget會(huì)收到右值,因?yàn)閡pdate_data_for_widget預(yù)期接受非const引用,我們不能向他傳遞右值。

解決方法是,按照如下方式改寫(xiě)(std::ref

std::thread t(update_data_for_widget, w, std::ref(data));

這樣就保證了傳入update_data_for_widget函數(shù)的不是變量data的臨時(shí)副本,而是指向變量data的引用,因此能夠編譯成功。

2.2 調(diào)用對(duì)象的方法

若要調(diào)用一個(gè)對(duì)象對(duì)應(yīng)的方法,則需要傳遞方法地址和對(duì)象地址,第三個(gè)參數(shù)作為該方法的第一個(gè)入?yún)ⅰ?/p>

class X {
public:void do_lengthy_work();};
X my_x;
std::thread t(&X::do_lengthy_work, &my_x);

上述代碼調(diào)用對(duì)象my_x的do_lengthy_work方法。

2.3 只能移動(dòng)的方式傳遞參數(shù)

3 移交線程歸屬權(quán)

http://www.risenshineclean.com/news/48280.html

相關(guān)文章:

  • 跳轉(zhuǎn)網(wǎng)站正在建設(shè)中seo網(wǎng)絡(luò)推廣經(jīng)理招聘
  • 自己做網(wǎng)站代理產(chǎn)品5188關(guān)鍵詞平臺(tái)
  • wordpress怎樣顯示子類目長(zhǎng)春網(wǎng)站seo
  • 希爾頓酒店網(wǎng)站建設(shè)的優(yōu)點(diǎn)網(wǎng)站推廣軟件哪個(gè)最好
  • 網(wǎng)站的客服怎么做小程序開(kāi)發(fā)收費(fèi)價(jià)目表
  • 蘇州網(wǎng)站制作服務(wù)營(yíng)銷的概念
  • 網(wǎng)站建設(shè)2019小說(shuō)排行榜百度
  • h5手機(jī)網(wǎng)站開(kāi)發(fā)demo品牌的宣傳及推廣
  • 建網(wǎng)站和做微信哪個(gè)好百度賬號(hào)注冊(cè)入口
  • 江蘇藝居建設(shè)有限公司網(wǎng)站整合營(yíng)銷什么意思
  • python網(wǎng)站開(kāi)發(fā) django桂平網(wǎng)絡(luò)推廣
  • 長(zhǎng)春網(wǎng)站建設(shè)方案seo服務(wù)內(nèi)容
  • icp網(wǎng)站負(fù)責(zé)人關(guān)鍵詞看片
  • 花都網(wǎng)站建設(shè) 駿域網(wǎng)站最好的推廣平臺(tái)排名
  • 網(wǎng)站開(kāi)發(fā)培訓(xùn)學(xué)費(fèi)今日軍事新聞?lì)^條打仗
  • 設(shè)計(jì)師服務(wù)平臺(tái)官網(wǎng)seo網(wǎng)絡(luò)營(yíng)銷外包公司
  • 電子商務(wù)網(wǎng)站建設(shè)利益分析網(wǎng)絡(luò)推廣外包代理
  • 丹陽(yáng)論壇學(xué)生班級(jí)優(yōu)化大師
  • 凡客網(wǎng)站的域名怎么做seo優(yōu)化代理
  • 網(wǎng)站服務(wù)搭建開(kāi)魯網(wǎng)站seo
  • 濟(jì)南網(wǎng)站建設(shè)優(yōu)化精準(zhǔn)客源app
  • 站群管理軟件百度軟件中心官網(wǎng)
  • 中企動(dòng)力做的網(wǎng)站被百度屏蔽seo第三方點(diǎn)擊軟件
  • 網(wǎng)站建設(shè)應(yīng)注重實(shí)用性湖北百度推廣電話
  • 男子做淫穢網(wǎng)站圖片seo優(yōu)化廠商
  • 網(wǎng)站建設(shè)管理報(bào)告免費(fèi)制作網(wǎng)站
  • 給關(guān)亨做網(wǎng)站的設(shè)計(jì)公司深圳關(guān)鍵詞推廣整站優(yōu)化
  • 視覺(jué)做的比較好的國(guó)外網(wǎng)站北京seo排名服務(wù)
  • 百度推廣電話客服湖南靠譜的關(guān)鍵詞優(yōu)化哪家好
  • 網(wǎng)站制作哪個(gè)軟件網(wǎng)站查詢域名