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

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

重慶模板建站軟件網(wǎng)站收錄服務(wù)

重慶模板建站軟件,網(wǎng)站收錄服務(wù),網(wǎng)絡(luò)銷售員每天做什么,網(wǎng)站建設(shè)制作設(shè)計營銷公司杭州目錄 一.POSIX線程庫 二.線程創(chuàng)建 1.創(chuàng)建線程接口 2.查看線程 3.多線程的健壯性問題 4.線程函數(shù)參數(shù)傳遞 5.線程id和地址空間 三.線程終止 1.pthread_exit 2.pthread_cancel 四.線程等待 五.線程分離 一.POSIX線程庫 站在內(nèi)核的角度,OS只有輕量級進(jìn)程…

目錄

一.POSIX線程庫

二.線程創(chuàng)建

1.創(chuàng)建線程接口

2.查看線程

3.多線程的健壯性問題

4.線程函數(shù)參數(shù)傳遞

5.線程id和地址空間

三.線程終止

1.pthread_exit

2.pthread_cancel

四.線程等待?

五.線程分離


一.POSIX線程庫

站在內(nèi)核的角度,OS只有輕量級進(jìn)程,沒有線程的概念,但是站在用戶的角度我們只有線程沒有輕量級進(jìn)程的概念。因?yàn)長inux下沒有真正意義上的線程,而是用進(jìn)程模擬的線程,所以Linux不會提供直接創(chuàng)建線程的系統(tǒng)調(diào)用,最多給我們提供創(chuàng)建輕量級進(jìn)程的接口。

所以linux對下對LWP的接口進(jìn)行封裝,對上給用戶提供線程控制的接口——POSIX線程庫,pthread庫,這是任何一個linux系統(tǒng)都會帶的庫,又叫原生線程庫。

POSIX線程:

  1. 與線程有關(guān)的函數(shù)構(gòu)成了一個完整的系列,絕大多數(shù)函數(shù)的名字都是以“pthread_”打頭的。
  2. 要使用這些函數(shù)庫,要通過引入頭文<pthread.h>。
  3. 鏈接這些線程函數(shù)庫時要使用編譯器命令的“-lpthread”選項(xiàng)。

?二.線程創(chuàng)建

1.創(chuàng)建線程接口

功能:創(chuàng)建一個新的線程。
原型:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
void *(*start_routine)(void*), void *arg);

參數(shù):

  1. thread:返回線程ID。
  2. attr:設(shè)置線程的屬性,attr為NULL表示使用默認(rèn)屬性。
  3. start_routine:是個函數(shù)地址,線程啟動后要執(zhí)行的函數(shù),該函數(shù)返回值是void*,參數(shù)是void*。
  4. arg:傳給線程啟動函數(shù)的參數(shù)。

返回值:

  • 成功返回0;失敗返回錯誤碼。

?測試代碼:

#include <iostream>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>
using namespace std;void *FuncRun(void *argc)
{while (1){cout << "I am thread,my pid:" << getpid() << endl;sleep(1);}
}int main()
{//線程idpthread_t id;//創(chuàng)建線程pthread_create(&id, NULL, FuncRun, NULL);while (1){cout << "I am main,my pid:" << getpid() << endl;sleep(1);}return 0;
}

測試結(jié)果:

說明:

  1. 線程沒有父子之分,但是線程有主線程,和新線程的區(qū)分。
  2. 我們可以看到,主線程pid和新線程的pid是相同的。因?yàn)樗麄儽旧砭褪峭粋€進(jìn)程的一部分。
  3. 新線程和主線程誰先被調(diào)度取決于調(diào)度器。

?2.查看線程

查看線程使用命令:

ps -aL

?3.多線程的健壯性問題

?測試代碼:

#include <iostream>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>using namespace std;void *FuncRun1(void *argc)
{int count = 0;while (1){count++;cout << "I am thread1,my pid:" << getpid() << endl;if (count == 5){int tmp = count / 0;}sleep(1);}
}
void *FuncRun2(void *argc)
{while (1){cout << "I am thread2,my pid:" << getpid() << endl;sleep(1);}
}int main()
{// 線程idpthread_t id1, id2;// 創(chuàng)建線程pthread_create(&id1, NULL, FuncRun1, NULL);pthread_create(&id2, NULL, FuncRun2, NULL);while (1){cout << "I am main,my pid:" << getpid() << endl;sleep(1);}return 0;
}

測試結(jié)果:

說明:

  1. 代碼其中有一個線程在第五秒的時候,會出現(xiàn)一個除0的問題。
  2. 當(dāng)一個線程因?yàn)槟骋粋€錯處而導(dǎo)致線程終止的時候,整個進(jìn)程也都會直接終止。
  3. 因?yàn)樾盘柺前l(fā)送給進(jìn)程的,最終OS直接對由信號做出的處理動作也是針對進(jìn)程的。

?4.線程函數(shù)參數(shù)傳遞

?我們想通過給線程函數(shù)傳參讓線程執(zhí)行更加復(fù)雜的任務(wù)。

#include <iostream>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>using namespace std;// 任務(wù),計算[1-top]的求和,并將結(jié)果存儲到sum中。
struct task
{task(int top, int num): _thread_name("thread" + to_string(num)), _top(top), _sum(0), _num(num){}string _thread_name; // 線程名字int _top;            // 計算數(shù)據(jù)范圍int _sum;            // 結(jié)果int _num;            // 線程編號
};// 線程函數(shù)
void *FuncRun(void *argc)
{task *t = (task *)argc;for (int i = 1; i <= t->_top; i++){t->_sum += i;}
}int main()
{// 線程idpthread_t id1, id2;// 創(chuàng)建線程task t1(100, 1);task t2(150, 2);pthread_create(&id1, NULL, FuncRun, &t1);pthread_create(&id2, NULL, FuncRun, &t2);// 等待線程計算完再輸出結(jié)果sleep(1);cout << t1._thread_name << ":[1-" << t1._top << "]=" << t1._sum << endl;cout << t2._thread_name << ":[1-" << t2._top << "]=" << t2._sum << endl;return 0;
}

測試結(jié)果:

說明:

  • 由于接口的設(shè)計上參數(shù)的類型是void* ,這也就使得我們可以給線程函數(shù)傳遞的參數(shù)是非常豐富的。

5.線程id和地址空間

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

pthread_t 到底是什么類型呢?取決于實(shí)現(xiàn)。對于Linux目前實(shí)現(xiàn)的NPTL實(shí)現(xiàn)而言,pthread_t類型的線程ID,本質(zhì)就是一個進(jìn)程地址空間上的一個地址。

我們在對線程做操作的時候,根本上是使用線程庫對線程進(jìn)行操作,那么線程庫本質(zhì)就是存在于linux上的動態(tài)庫,在我們使用線程庫的時候,線程庫也會向普通的動態(tài)庫一樣加載到共享區(qū)中,我們使用線程庫方法就是訪問自己的地址空間。

線程庫中需要被管理的線程會有很多,線程庫也必然實(shí)現(xiàn)了線程的數(shù)據(jù)結(jié)構(gòu)——TCB(線程控制塊)。

每個線程都有自己的TCB,和獨(dú)立的上下文數(shù)據(jù),以及線程??臻g。pthread_t 就是指向他們的首地址的一個地址。

?三.線程終止

如果需要只終止某個線程而不終止整個進(jìn)程,可以有三種方法:

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

1.pthread_exit

功能:線程終止.
原型:void pthread_exit(void *value_ptr);
參數(shù):value_ptr:value_ptr不要指向一個局部變量,返回線程結(jié)果。
返回值:無返回值,跟進(jìn)程一樣,線程結(jié)束的時候無法返回到它的調(diào)用者(自身)。

?測試代碼:

#include <iostream>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>using namespace std;void *FuncRun1(void *argc)
{int count = 0;while (1){count++;cout << "I am thread-1-count:" << count << endl;sleep(1);// 三秒后線程1退出if (count == 3){pthread_exit(NULL);}}
}void *FuncRun2(void *argc)
{int count = 0;while (1){count++;cout << "I am thread-2-count:" << count << endl;sleep(1);// 三秒后線程2退出if (count == 3){pthread_exit(NULL);}}
}int main()
{// 線程idpthread_t id1, id2;// 創(chuàng)建線程pthread_create(&id1, NULL, FuncRun1, NULL);pthread_create(&id2, NULL, FuncRun2, NULL);while (1){cout << "I am main,my pid:" << getpid() << endl;sleep(1);}return 0;
}

測試結(jié)果:

說明:

  1. 線程在退出后,主線程并沒有受到影響,進(jìn)程也有沒受到影響。
  2. 需要注意,pthread_exit或者return返回的指針?biāo)赶虻膬?nèi)存單元必須是全局的或者是用malloc分配的,不能在線程函數(shù)的棧上分配,因?yàn)楫?dāng)其它線程得到這個返回指針時線程函數(shù)已經(jīng)退出了。

2.pthread_cancel

功能:取消一個執(zhí)行中的線程
原型:int pthread_cancel(pthread_t thread);
參數(shù):thread:線程ID
返回值:成功返回0;失敗返回錯誤碼

?測試代碼:


#include <iostream>
#include <cstdio>
#include <pthread.h>
#include <unistd.h>using namespace std;void *FuncRun1(void *argc)
{int count = 0;while (1){count++;cout << "I am thread-1-count:" << count << endl;sleep(1);}
}
void *FuncRun2(void *argc)
{int count = 0;while (1){count++;cout << "I am thread-2-count:" << count << endl;sleep(1);}
}
int main()
{// 線程idpthread_t id1, id2;// 創(chuàng)建線程pthread_create(&id1, NULL, FuncRun1, NULL);pthread_create(&id2, NULL, FuncRun2, NULL);int count = 0;while (1){count++;sleep(1);if (count == 3){// 三秒后終止線程pthread_cancel(id1);pthread_cancel(id2);}cout << "I am main" << endl;}return 0;
}

測試結(jié)果:

四.線程等待?

為什么需要線程等待?

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

?功能:等待線程結(jié)束。
原型:int pthread_join(pthread_t thread, void **value_ptr);
參數(shù):thread:線程ID。
value_ptr:它指向一個指針,后者指向線程的返回值。
返回值:成功返回0;失敗返回錯誤碼。

調(diào)用該函數(shù)的線程將掛起等待,直到id為thread的線程終止。thread線程以不同的方法終止,通過pthread_join得到的終止?fàn)顟B(tài)是不同的,總結(jié)如下:?

  1. 如果thread線程通過return返回,value_ ptr所指向的單元里存放的是thread線程函數(shù)的返回值。
  2. 如果thread線程被別的線程調(diào)用pthread_ cancel異常終掉,value_ ptr所指向的單元里存放的是常數(shù),PTHREAD_ CANCELED。
  3. 如果thread線程是自己調(diào)用pthread_exit終止的,value_ptr所指向的單元存放的是傳給pthread_exit的參數(shù)。
  4. 如果對thread線程的終止?fàn)顟B(tài)不感興趣,可以傳NULL給value_ ptr參數(shù)。

?測試代碼:

void *FuncRun1(void *argc)
{int *top = (int *)argc;int *sum = new int;for (int i = 1; i <= *top; i++){*sum += i;}// 線程退出pthread_exit(sum);
}void *FuncRun2(void *argc)
{int *top = (int *)argc;int *sum = new int;for (int i = 1; i <= *top; i++){*sum += i;}// 線程退出return sum;
}void *FuncRun3(void *argc)
{int *top = (int *)argc;int *sum = new int;for (int i = 1; i <= *top; i++){*sum += i;sleep(1);}free(sum);// 線程退出
}int main()
{int top1 = 100;int top2 = 150;int top3 = 200;pthread_t id1;pthread_t id2;pthread_t id3;pthread_create(&id1, NULL, FuncRun1, &top1);pthread_create(&id2, NULL, FuncRun2, &top2);pthread_create(&id3, NULL, FuncRun3, &top3);pthread_cancel(id3);// 接受線程返回數(shù)據(jù)void *ret_ptr1;void *ret_ptr2;void *ret_ptr3;// 等待線程pthread_join(id1, &ret_ptr1);pthread_join(id2, &ret_ptr2);pthread_join(id3, &ret_ptr3);cout << "ret1:" << *((int *)ret_ptr1) << endl;free(ret_ptr1);cout << "ret2:" << *((int *)ret_ptr2) << endl;free(ret_ptr2);if (ret_ptr3 == PTHREAD_CANCELED)cout << "ret3:PTHREAD_CANCELED" << endl;return 0;
}

測試結(jié)果:

五.線程分離

  1. ?默認(rèn)情況下,新創(chuàng)建的線程是joinable的,線程退出后,需要對其進(jìn)行pthread_join操作,否則無法釋放資源,從而造成系統(tǒng)泄漏。
  2. 如果不關(guān)心線程的返回值,join是一種負(fù)擔(dān),這個時候,我們可以告訴系統(tǒng),當(dāng)線程退出時,自動釋放線程資源。
int pthread_detach(pthread_t thread);

可以是線程組內(nèi)其他線程對目標(biāo)線程進(jìn)行分離,也可以是線程自己分離:

pthread_detach(pthread_self());

joinable分離是沖突的,一個線程不能既是joinable又是分離的。

測試代碼:


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <pthread.h>
#include <unistd.h>using namespace std;
void *FuncRun(void *argc)
{// 線程分離pthread_detach(pthread_self());int count = 0;while (1){count++;cout << "I am thread-count:" << count << endl;sleep(1);}
}int main()
{pthread_t tid;int n = pthread_create(&tid, NULL, FuncRun, NULL);if (n != 0){cerr << "pthread_create:" << strerror(errno) << endl;}sleep(2);// 線程已經(jīng)分離,再去線程等待,pthread_join會立即報錯。if (pthread_join(tid, NULL) == 0){printf("pthread wait success\n");}else{printf("pthread wait failed\n");}return 0;
}

測試結(jié)果:

?

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

相關(guān)文章:

  • 唐山公司網(wǎng)站建設(shè) 中企動力沈陽關(guān)鍵詞seo排名
  • 專業(yè)做俄語網(wǎng)站建設(shè)司360搜索首頁網(wǎng)址是多少
  • 自己搭建網(wǎng)站只有文字品牌網(wǎng)站建設(shè)方案
  • 蘇州seo網(wǎng)絡(luò)優(yōu)化公司歐美seo查詢
  • 廣州海珠網(wǎng)站開發(fā)定制大數(shù)據(jù)分析師
  • 做網(wǎng)站用什么云服務(wù)器常用的營銷策略
  • cc域名做網(wǎng)站怎么樣熱點(diǎn)新聞事件
  • 網(wǎng)站的建設(shè)模式是指什么時候開始百度seo優(yōu)化服務(wù)項(xiàng)目
  • 網(wǎng)站開發(fā)的一般步驟2023第二波疫情已經(jīng)到來了嗎
  • php網(wǎng)站的登陸注冊怎末做的整合營銷傳播工具有哪些
  • 做旅游網(wǎng)站賺錢嗎專業(yè)的網(wǎng)站建設(shè)公司
  • 生意網(wǎng)抖音seo查詢工具
  • 手機(jī)廣告設(shè)計與制作軟件南京seo建站
  • 在線做海報的網(wǎng)站廣州百度seo排名
  • rp如何做網(wǎng)站電商平臺有哪些
  • 網(wǎng)站推廣優(yōu)化平臺淘寶關(guān)鍵詞排名
  • 建筑網(wǎng)格布搭接seo經(jīng)典案例分析
  • 網(wǎng)站開發(fā)2019最近的新聞有哪些
  • 官方網(wǎng)站怎樣做網(wǎng)站快速優(yōu)化排名方法
  • php網(wǎng)站后臺管理系統(tǒng)源碼北京網(wǎng)絡(luò)營銷外包公司哪家好
  • 杭州網(wǎng)站建設(shè)怎么樣交換友情鏈接的意義是什么
  • 手把手做網(wǎng)站友情鏈接檢測659292
  • 拿品牌做網(wǎng)站算侵權(quán)嗎google海外推廣
  • 國外做化學(xué)申報的網(wǎng)站做推廣的公司
  • 鄭州哪些公司做網(wǎng)站建設(shè)全網(wǎng)推廣的方式
  • 花溪建設(shè)村鎮(zhèn)銀行官方網(wǎng)站百度提交入口的網(wǎng)址
  • 沒有后臺的網(wǎng)站怎么做排名搜索風(fēng)云榜入口
  • flash怎么做網(wǎng)站抖音流量推廣神器軟件
  • 網(wǎng)站的風(fēng)格有哪些什么是seo
  • 電子商務(wù)網(wǎng)站建設(shè)是什么重慶森林為什么叫這個名字