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

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

wordpress拉寬seo文章優(yōu)化技巧

wordpress拉寬,seo文章優(yōu)化技巧,網(wǎng)站世界排名怎么做,安平做網(wǎng)站做推廣電話目錄 ?編輯 POSIX線程庫 多線程創(chuàng)建 獨(dú)立棧結(jié)構(gòu) 獲取線程ID pthread_self 線程終止 return終止線程 pthread_exit pthread_cancel 線程等待 退出碼問題 線程分離 測(cè)試 線程ID及地址空間布局 ?編輯 POSIX線程庫 pthread線程庫是 POSIX線程庫的一部分&#xf…

目錄

?編輯

POSIX線程庫

?多線程創(chuàng)建

獨(dú)立棧結(jié)構(gòu)?

獲取線程ID?

pthread_self?

?線程終止

return終止線程

pthread_exit

pthread_cancel

線程等待

??退出碼問題

?線程分離

測(cè)試?

線程ID及地址空間布局?

?編輯


POSIX線程庫

pthread線程庫是 POSIX線程庫的一部分,POSIX線程庫也叫原生線程庫;

????????遵守 POSIX標(biāo)準(zhǔn):與線程有關(guān)的函數(shù)構(gòu)成了一個(gè)完整的系列,絕大多數(shù)函數(shù)的名字都是以“pthread_”開頭的
要使用這些函數(shù)庫,要通過引入頭文<pthread.h>
鏈接這些線程函數(shù)庫時(shí)要使用編譯器命令的 “-lpthread” 選項(xiàng);

成功返回0,失敗返回-1

?多線程創(chuàng)建

主線程創(chuàng)建一批線程;

沒有在循環(huán)創(chuàng)建中添加sleep();

void* handler(void* arg)
{const char* name = (const char*)arg;while(true){cout<<"new thread sucess name:"<<name<<endl;sleep(1);}
}int main()
{pthread_t tid;char namebuff[64];for(int i = 0;i<5;i++)  {//格式化snprintf(namebuff,sizeof(namebuff),"%s:%d","thread:",i+1);pthread_create(&tid,nullptr,handler,namebuff);  //}while(true){cout << "new thread create success, I am main thread" << endl;sleep(1);}return 0;
}

?觀察發(fā)現(xiàn),線程編號(hào)不是我們預(yù)期的從1.2.3..開始的,而是到了最后一個(gè)線程名字;

而且線程確實(shí)創(chuàng)建出來了;

添加循環(huán)創(chuàng)建時(shí)sleep()函數(shù)?;將數(shù)組地址改為拷貝

//把參數(shù)封成結(jié)構(gòu)體
class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的進(jìn)行強(qiáng)制類型轉(zhuǎn)換,C++11int cnt = 10;while(cnt){cout << "cnt:" << cnt-- << "  &cnt:" << &cnt << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 10//創(chuàng)建一批線程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();//每次循環(huán)new的都是一個(gè)新對(duì)象snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使線程下標(biāo)從1開始pthread_create(&td->tid, nullptr, start_routine, td);}//主線程while(1){cout << "new thread create success, name:main thread" << endl;sleep(1);}return 0;
}
  • 主線程創(chuàng)建新線程太快了,新線程都沒有機(jī)會(huì)運(yùn)行,主線程就把10個(gè)新線程創(chuàng)建完畢了,
  • 而傳參namebuffer傳過去的是 緩沖區(qū)namebuffer的起始地址,
  • 第十個(gè)線程創(chuàng)建完成之后,緩沖區(qū)的內(nèi)容都被第十個(gè)線程的編號(hào)內(nèi)容覆蓋了,所以第一次現(xiàn)象線程的編號(hào)都是 10

獨(dú)立棧結(jié)構(gòu)?

線程棧主要用于存儲(chǔ)線程的局部變量、函數(shù)參數(shù)以及調(diào)用堆棧。當(dāng)一個(gè)線程開始執(zhí)行時(shí),它的棧空間會(huì)被初始化,并且隨著線程的執(zhí)行,??臻g會(huì)被動(dòng)態(tài)地?cái)U(kuò)展或收縮。

//把參數(shù)封成結(jié)構(gòu)體
class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的進(jìn)行強(qiáng)制類型轉(zhuǎn)換,C++11int cnt = 10;while(cnt){cout << "cnt:" << cnt-- << "  &cnt:" << &cnt << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 10//創(chuàng)建一批線程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();//每次循環(huán)new的都是一個(gè)新對(duì)象snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使線程下標(biāo)從1開始pthread_create(&td->tid, nullptr, start_routine, td);}//主線程while(1){cout << "new thread create success, name:main thread" << endl;sleep(1);}return 0;
}

在函數(shù)內(nèi)部定義的變量叫局部變量,具有臨時(shí)性,在多線程的情況下依舊適用,因?yàn)槊總€(gè)線程都有自己的獨(dú)立棧結(jié)構(gòu)?

獲取線程ID?

常見獲取線程ID的方式有兩種:

  • 創(chuàng)建線程時(shí)通過輸出型參數(shù)獲得
  • 通過調(diào)用pthread_self函數(shù)獲得

pthread_self?

?

void* start_routine(void* args)
{//安全轉(zhuǎn)換std::string name = static_cast<const char*>(args);while(true){std::cout<<name<<" running ...,ID: "<<pthread_self()<<std::endl;sleep(1);}
}int main()
{pthread_t thread_id;//創(chuàng)建一個(gè)線程pthread_create(&thread_id,nullptr,start_routine,(void*)"thread 1:");//打印一下主線程的IDwhile(true){std::cout<<"main thread"<<" ID: "<<pthread_self()<<std::endl;sleep(1);}// 等待子線程結(jié)束pthread_join(thread_id, NULL);return 0;
}

?

?線程終止

如果需要只終止某個(gè)線程而不終止整個(gè)進(jìn)程

可以有三種方法:

  • 從線程函數(shù)return。這種方法對(duì)主線程不適用,從main函數(shù)return相當(dāng)于調(diào)用exit,整個(gè)進(jìn)程退出
  • 線程可以調(diào)用 pthread_ exit 終止自己
  • 一個(gè)線程可以調(diào)用 pthread_ cancel 終止同一進(jìn)程中的另一個(gè)線程

return終止線程

在多線程程序中,return關(guān)鍵字的使用有所不同

當(dāng)非主線程時(shí),僅表示該線程將終止其執(zhí)行;在main函數(shù)中使用return則意味著整個(gè)進(jìn)程將退出,這會(huì)導(dǎo)致進(jìn)程的所有資源被釋放。

用例

主線程創(chuàng)建多個(gè)新線程后,休眠2秒,然后進(jìn)行return,那么整個(gè)進(jìn)程也就退出了??

class ThreadData
{
public:pthread_t tid;char namebuffer[64];
};void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);//static_cast 安全的進(jìn)行強(qiáng)制類型轉(zhuǎn)換,C++11int cnt = 10;while(cnt){cout << "new thread create success, name:" << td->namebuffer << "  cnt:" << cnt-- << endl;sleep(1);}delete td;return nullptr;
}int main()
{
#define NUM 3//創(chuàng)建一批線程for(int i = 0; i < NUM; i++){ThreadData* td = new ThreadData();snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", i+1);//i+1 使線程下標(biāo)從1開始pthread_create(&td->tid, nullptr, start_routine, td);}//主線程cout << "new thread create success, name:main thread" << endl;sleep(2);//主線程兩秒后退出return 0;
}

?如果非主線程執(zhí)行到return,僅代表該線程結(jié)束,線程退出?

pthread_exit

?函數(shù)終止線程?

  • exit 是用來終止進(jìn)程的,任何一個(gè)執(zhí)行流調(diào)用 exit,都會(huì)使整個(gè)進(jìn)程退出;
  • pthread_exit函數(shù)的功能就是終止線程;

?注意

當(dāng)pthread_exit()和return時(shí),如果返回值是一個(gè)指針,該指針指向的內(nèi)存空間應(yīng)該是全局的或者malloc分配的(new 本質(zhì)也是malloc),防止后面有其它線程通過該指針訪問出錯(cuò);

????????當(dāng)然,為了避免潛在威脅,最好確保返回的指針是指向全局,malloc開辟的。這樣可以確保即使線程退出,其他線程仍然可以安全地訪問這些內(nèi)存。不能在線程函數(shù)的棧上分配,因?yàn)楫?dāng)其它線程得到這個(gè)返回指針時(shí)線程函數(shù)已經(jīng)退出了 ;

pthread_cancel

?函數(shù)取消線程?

// 定義一個(gè)用于存儲(chǔ)線程數(shù)據(jù)的類
class ThreadData
{
public:int number;     // 線程編號(hào)pthread_t tid;  // 線程IDchar namebuffer[64]; // 緩沖區(qū),用于存儲(chǔ)線程名稱
};// 線程函數(shù)
void* start_routine(void* args)
{ThreadData* td = static_cast<ThreadData*>(args);int cnt = 10;while (cnt > 0){cout << td->namebuffer << "  cnt:" << cnt-- << endl;sleep(1);}// 使用 pthread_exit 返回線程編號(hào)pthread_exit((void*)td->number);
}int main()
{vector<ThreadData*> threads; // 用于存儲(chǔ)線程數(shù)據(jù)的向量
#define NUM 5 // 定義要?jiǎng)?chuàng)建的線程數(shù)量for (int i = 0; i < NUM; i++)     // 創(chuàng)建一批線程{ThreadData* td = new ThreadData();    // 創(chuàng)建 ThreadData 實(shí)例td->number = i + 1; // 設(shè)置線程編號(hào)snprintf(td->namebuffer, sizeof(td->namebuffer), "%s:%d", "thread", td->number);pthread_create(&td->tid, nullptr, start_routine, td);threads.push_back(td);    // 把每個(gè)線程的信息 push 到 threads 向量中}// 主線程for (auto& iter : threads){// 輸出創(chuàng)建成功的線程信息cout << "create thread: " << iter->namebuffer << " : " << iter->tid << " success" << endl;}sleep(5);   // 主線程休眠5秒// 取消線程for (auto& iter : threads){// 取消線程pthread_cancel(iter->tid);cout << "pthread_cancel: " << iter->namebuffer << endl;}// 等待線程結(jié)束for (auto& iter : threads){void* ret = nullptr;int n = pthread_join(iter->tid, &ret);    // 等待線程結(jié)束,并獲取線程返回值// 斷言assert(n == 0);// 輸出線程結(jié)束的信息和線程退出時(shí)返回的值cout << "join: " << iter->namebuffer << " success, thread_exit_code: " << (long long)ret << endl;delete iter;      // 釋放 ThreadData 實(shí)例}// 主線程退出cout << "main thread quit" << endl;return 0;
}

?

一個(gè)線程被取消,它的退出碼是 -1

線程等待

線程跟進(jìn)程一樣,創(chuàng)建后也需要主線程等待回收,如果主線程不對(duì)新線程進(jìn)行等待,如果主線程不對(duì)新創(chuàng)建的線程進(jìn)行等待,那么這個(gè)新線程的資源將不會(huì)被及時(shí)回收。這會(huì)導(dǎo)致類似“僵尸進(jìn)程”的問題,也就是內(nèi)存泄漏 ;

  • 已經(jīng)退出的線程,其空間沒有被釋放,仍然在進(jìn)程的地址空間內(nèi)。
  • 創(chuàng)建新的線程不會(huì)復(fù)用剛才退出線程的地址空間

??退出碼問題

?

  • void* retval 和 void** retval 有什么關(guān)系??
  • 線程函數(shù)start_routine函數(shù)的返回值類型也是 void*,?start_routine函數(shù)的返回值返回到哪里??
  • 我們?cè)趺传@取線程的退出碼,即線程的返回值??

pthread_join函數(shù)的參數(shù) void** retval 是一個(gè)輸出型參數(shù),用來獲取線程函數(shù)結(jié)束時(shí),返回的退出結(jié)果
void** retval 是用來獲取線程函數(shù)返回的退出結(jié)果,因?yàn)榫€程函數(shù)的返回值是 void*,所以需要用 void** 來接受 void*
注意:線程函數(shù)返回的退出結(jié)果是返回在線程庫當(dāng)中,參數(shù) void** retval 需要去線程庫里面接受才可以返回

?線程分離

新創(chuàng)建的線程是 joinable(可以被等待)的。這意味著線程退出后,需要對(duì)其執(zhí)行 pthread_join 操作來釋放資源,否則這些資源將不會(huì)被釋放,從而可能導(dǎo)致系統(tǒng)資源泄漏。如果不關(guān)心線程的返回值的話,線程等待pthread_join是一種負(fù)擔(dān);
可以使用?pthread_detach來分離線程。分離后的線程會(huì)在退出時(shí)自動(dòng)釋放其資源,無需主線程進(jìn)行?pthread_join操作。

?

測(cè)試?

// 將線程ID轉(zhuǎn)換為字符串
string changeID(const pthread_t& thread_id)
{char tid[128];// 將線程ID格式化為十六進(jìn)制字符串snprintf(tid, sizeof(tid), "0x%x", thread_id);return tid;
}// 線程函數(shù)
void* start_routine(void* args)
{string threadname = static_cast<const char*>(args);int cnt = 5;while (cnt > 0){// 輸出線程名稱和線程ID cout << threadname << " running..., threadID:" << changeID(pthread_self()) << endl;sleep(1);cnt--;}// 線程函數(shù)結(jié)束return nullptr;
}int main()
{pthread_t tid;// 創(chuàng)建一個(gè)新線程pthread_create(&tid, nullptr, start_routine, (void*)"thread 1");// 分離線程pthread_detach(tid); // 分離線程后,線程將在退出時(shí)自動(dòng)釋放資源// 線程默認(rèn)是 joinable 的,一旦分離,就不允許再使用 pthread_join// pthread_join(tid, nullptr); // 這里如果嘗試使用 pthread_join 會(huì)引發(fā)錯(cuò)誤// 獲取主線程IDstring mainID = changeID(pthread_self()); // 主線程IDwhile (1){// 輸出主線程的信息     由于新線程已經(jīng)被分離,其ID實(shí)際上已經(jīng)不再有效,只是為了展示。cout << "main running..., mainID:" << mainID << ", new threadID:" << changeID(tid) << endl;sleep(1);}return 0;
}

線程ID及地址空間布局?

pthread_create函數(shù)會(huì)產(chǎn)生一個(gè)線程ID,存放在第一個(gè)參數(shù)指向的地址中。該線程ID和前面說的線程ID不是一回事。
前面講的線程ID屬于進(jìn)程調(diào)度的范疇。因?yàn)榫€程是輕量級(jí)進(jìn)程,是操作系統(tǒng)調(diào)度器的最小單位,所以需要一個(gè)數(shù)值來唯一表示該線程。
pthread_create函數(shù)第一個(gè)參數(shù)指向一個(gè)虛擬內(nèi)存單元,該內(nèi)存單元的地址即為新創(chuàng)建線程的線程ID,屬于NPTL線程庫的范疇。線程庫的后續(xù)操作,就是根據(jù)該線程ID來操作線程的。

用戶級(jí)線程:線程ID值就是庫中結(jié)構(gòu)體(TCB)對(duì)象的地址?

http://m.risenshineclean.com/news/61551.html

相關(guān)文章:

  • 最火的網(wǎng)絡(luò)銷售平臺(tái)seo顧問合同
  • 高端網(wǎng)站定制方案seo網(wǎng)絡(luò)推廣培訓(xùn)
  • 高端網(wǎng)站建設(shè)kgu網(wǎng)站建設(shè)網(wǎng)站
  • b2b網(wǎng)站建設(shè)案例鄭州網(wǎng)絡(luò)營銷顧問
  • 昆明網(wǎng)站seo報(bào)價(jià)推廣普通話手抄報(bào)內(nèi)容大全資料
  • 網(wǎng)站常見攻擊營銷型網(wǎng)站建設(shè)步驟
  • 江蘇網(wǎng)站設(shè)計(jì)建站模板
  • 做網(wǎng)站的銷售簡(jiǎn)述在線推廣網(wǎng)站的方法
  • 個(gè)體工商戶 做經(jīng)營性網(wǎng)站網(wǎng)站鏈接查詢
  • wifi擴(kuò)展器做網(wǎng)站百度資源平臺(tái)鏈接提交
  • 鄭州好的網(wǎng)站設(shè)計(jì)公司搜索引擎關(guān)鍵詞排名優(yōu)化
  • 項(xiàng)城做網(wǎng)站搜索引擎的網(wǎng)址有哪些
  • 政府門戶網(wǎng)站什么意思搜索引擎優(yōu)化seo優(yōu)惠
  • wordpress添加關(guān)鍵詞描述seo優(yōu)化在線診斷
  • 蘇州營銷網(wǎng)站建設(shè)公司杭州seo搜索引擎優(yōu)化
  • vps網(wǎng)站設(shè)置搜索引擎優(yōu)化的基礎(chǔ)是什么
  • 四川專門做招聘酒的網(wǎng)站網(wǎng)頁制作公司排名
  • 網(wǎng)站建設(shè)公司 南京舉例一個(gè)成功的網(wǎng)絡(luò)營銷案例
  • 網(wǎng)站開發(fā)平臺(tái)的定義鴻星爾克網(wǎng)絡(luò)營銷案例分析
  • 重慶市建設(shè)網(wǎng)站站長(zhǎng)網(wǎng)站seo查詢
  • 怎么查網(wǎng)站有沒有做404營銷推廣工作內(nèi)容
  • 網(wǎng)上商城建設(shè)seo策略是什么意思
  • 杭州設(shè)計(jì)公司網(wǎng)站排名黃岡免費(fèi)網(wǎng)站推廣平臺(tái)匯總
  • 用asp.net做的網(wǎng)站實(shí)例行業(yè)關(guān)鍵詞搜索排名
  • 商城類的網(wǎng)站怎么做北京競(jìng)價(jià)托管代運(yùn)營
  • 杭州做網(wǎng)站hzyze域名在線查詢
  • 廣州免費(fèi)接種宮頸癌疫苗推廣關(guān)鍵詞優(yōu)化
  • 個(gè)人做網(wǎng)站猛賺錢seo優(yōu)化有百度系和什么
  • vue.js做的網(wǎng)站資源貓
  • 找手工活帶回家做的找工作哪個(gè)網(wǎng)站最靠譜內(nèi)容營銷