真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Linux多線程編程的示例分析

這篇文章主要介紹了Linux多線程編程的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括秦都網(wǎng)站建設(shè)、秦都網(wǎng)站制作、秦都網(wǎng)頁(yè)制作以及秦都網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,秦都網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到秦都省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

1 線程基本知識(shí)

進(jìn)程是資源管理的基本單元,而線程是系統(tǒng)調(diào)度的基本單元,線程是操作系統(tǒng)能夠進(jìn)行調(diào)度運(yùn)算的最小單位,它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。一條線程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)。

一個(gè)進(jìn)程在某一個(gè)時(shí)刻只能做一件事情,有了多個(gè)控制線程以后,在程序的設(shè)計(jì)成在某一個(gè)時(shí)刻能夠做不止一件事,每個(gè)線程處理獨(dú)自的任務(wù)。

需要注意的是:即使程序運(yùn)行在單核處理器上,也能夠得到多線程編程模型的好處。處理器的數(shù)量并不影響程序結(jié)構(gòu),所以不管處理器個(gè)數(shù)多少,程序都可以通過(guò)線程得以簡(jiǎn)化。

linux操作系統(tǒng)使用符合POSIX線程作為系統(tǒng)標(biāo)準(zhǔn)線程,該P(yáng)OSIX線程標(biāo)準(zhǔn)定義了一整套操作線程的API。

2. 線程標(biāo)識(shí)

與進(jìn)程有一個(gè)ID一樣,每個(gè)線程有一個(gè)線程ID,所不同的是,進(jìn)程ID在整個(gè)系統(tǒng)中是唯一的,而線程是依附于進(jìn)程的,其線程ID只有在所屬的進(jìn)程中才有意義。線程ID用pthread_t表示。

//pthread_self直接返回調(diào)用線程的ID
include 
pthread_t pthread_self(void);

判斷兩個(gè)線程ID的大小是沒(méi)有任何意義的,但有時(shí)可能需要判斷兩個(gè)給定的線程ID是否相等,使用以下接口:

//pthread_equal如果t1和t2所指定的線程ID相同,返回0;否則返回非0值。
include 
int pthread_equal(pthread_t t1, pthread_t t2);

3. 線程創(chuàng)建

一個(gè)線程的生命周期起始于它被創(chuàng)建的那一刻,創(chuàng)建線程的接口:

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

函數(shù)參數(shù):

thread(輸出參數(shù)),由pthread_create在線程創(chuàng)建成功后返回的線程句柄,該句柄在后續(xù)操作線程的API中用于標(biāo)志該新建的線程; 
start_routine(輸入?yún)?shù)),新建線程的入口函數(shù); 
arg(輸入?yún)?shù)),傳遞給新線程入口函數(shù)的參數(shù); 
attr(輸入?yún)?shù)),指定新建線程的屬性,如線程棧大小等;如果值為NULL,表示使用系統(tǒng)默認(rèn)屬性。

函數(shù)返回值:

成功,返回0; 
失敗,返回相關(guān)錯(cuò)誤碼。

需要注意:

1.主線程,這是一個(gè)進(jìn)程的初始線程,其入口函數(shù)為main函數(shù)。
2.新線程的運(yùn)行時(shí)機(jī),一個(gè)線程被創(chuàng)建之后有可能不會(huì)被馬上執(zhí)行,甚至,在創(chuàng)建它的線程結(jié)束后還沒(méi)被執(zhí)行;也有可能新線程在當(dāng)前線程從pthread_create前就已經(jīng)在運(yùn)行,甚至,在pthread_create前從當(dāng)前線程返回前新線程就已經(jīng)執(zhí)行完畢。

程序?qū)嵗?/p>

#include 
#include 
#include 
#include 

void printids(const char *s){
 pid_t pid;
 pthread_t tid;
 pid = getpid();
 tid = pthread_self();
 printf("%s, pid %lu tid %lu (0x%lx)\n",s,(unsigned long)pid,(unsigned long)tid,
 (unsigned long)tid);
}

void *thread_func(void *arg){
 printids("new thread: ");
 return ((void*)0);
}
int main() {
 int err;
 pthread_t tid;
 err = pthread_create(&tid,NULL,thread_func,NULL);
 if (err != 0) {
  fprintf(stderr,"create thread fail.\n");
 exit(-1); 
 }
 printids("main thread:");
 sleep(1); 
 return 0;
}

注意上述的程序中,主線程休眠一秒,如果不休眠,則主線程不休眠,則其可能會(huì)退出,這樣新線程可能不會(huì)被運(yùn)行,我自己注釋掉sleep函數(shù),發(fā)現(xiàn)好多次才能讓新線程輸出。

編譯命令:

gcc -o thread thread.c -lpthread

運(yùn)行結(jié)果如下:

main thread:, pid 889 tid 139846854309696 (0x7f30a212f740)
new thread: , pid 889 tid 139846845961984 (0x7f30a1939700)

可以看到兩個(gè)線程的進(jìn)程ID是相同的。其共享進(jìn)程中的資源。

4. 線程終止

線程的終止分兩種形式:被動(dòng)終止和主動(dòng)終止

被動(dòng)終止有兩種方式:

1.線程所在進(jìn)程終止,任意線程執(zhí)行exit、_Exit或者_(dá)exit函數(shù),都會(huì)導(dǎo)致進(jìn)程終止,從而導(dǎo)致依附于該進(jìn)程的所有線程終止。
2.其他線程調(diào)用pthread_cancel請(qǐng)求取消該線程。

主動(dòng)終止也有兩種方式:

1.在線程的入口函數(shù)中執(zhí)行return語(yǔ)句,main函數(shù)(主線程入口函數(shù))執(zhí)行return語(yǔ)句會(huì)導(dǎo)致進(jìn)程終止,從而導(dǎo)致依附于該進(jìn)程的所有線程終止。
2.線程調(diào)用pthread_exit函數(shù),main函數(shù)(主線程入口函數(shù))調(diào)用pthread_exit函數(shù), 主線程終止,但如果該進(jìn)程內(nèi)還有其他線程存在,進(jìn)程會(huì)繼續(xù)存在,進(jìn)程內(nèi)其他線程繼續(xù)運(yùn)行。

線程終止函數(shù):

include 
void pthread_exit(void *retval);

線程調(diào)用pthread_exit函數(shù)會(huì)導(dǎo)致該調(diào)用線程終止,并且返回由retval指定的內(nèi)容。
注意:retval不能指向該線程的??臻g,否則可能成為野指針!

5. 管理線程的終止

5.1 線程的連接

一個(gè)線程的終止對(duì)于另外一個(gè)線程而言是一種異步的事件,有時(shí)我們想等待某個(gè)ID的線程終止了再去執(zhí)行某些操作,pthread_join函數(shù)為我們提供了這種功能,該功能稱為線程的連接:

include 
int pthread_join(pthread_t thread, void **retval);

參數(shù)說(shuō)明:

thread(輸入?yún)?shù)),指定我們希望等待的線程 
retval(輸出參數(shù)),我們等待的線程終止時(shí)的返回值,就是在線程入口函數(shù)中return的值或者調(diào)用pthread_exit函數(shù)的參數(shù)

返回值:

成功時(shí),返回0 
錯(cuò)誤時(shí),返回正數(shù)錯(cuò)誤碼

當(dāng)線程X連接線程Y時(shí),如果線程Y仍在運(yùn)行,則線程X會(huì)阻塞直到線程Y終止;如果線程Y在被連接之前已經(jīng)終止了,那么線程X的連接調(diào)用會(huì)立即返回。

連接線程其實(shí)還有另外一層意義,一個(gè)線程終止后,如果沒(méi)有人對(duì)它進(jìn)行連接,那么該終止線程占用的資源,系統(tǒng)將無(wú)法回收,而該終止線程也會(huì)成為僵尸線程。因此,當(dāng)我們?nèi)ミB接某個(gè)線程時(shí),其實(shí)也是在告訴系統(tǒng)該終止線程的資源可以回收了。

注意:對(duì)于一個(gè)已經(jīng)被連接過(guò)的線程再次執(zhí)行連接操作, 將會(huì)導(dǎo)致無(wú)法預(yù)知的行為!

5.2 線程的分離

有時(shí)我們并不在乎某個(gè)線程是不是已經(jīng)終止了,我們只是希望如果某個(gè)線程終止了,系統(tǒng)能自動(dòng)回收掉該終止線程所占用的資源。pthread_detach函數(shù)為我們提供了這個(gè)功能,該功能稱為線程的分離:

#include 
int pthread_detach(pthread_t thread);

默認(rèn)情況下,一個(gè)線程終止了,是需要在被連接后系統(tǒng)才能回收其占有的資源的。如果我們調(diào)用pthread_detach函數(shù)去分離某個(gè)線程,那么該線程終止后系統(tǒng)將自動(dòng)回收其資源。

/*
* 文件名: thread_sample1.c
* 描述:演示線程基本操作
*/
#include 
#include 
#include 
#include 

/*子線程1入口函數(shù)*/
void *thread_routine1(void *arg)
{
 fprintf(stdout, "thread1: hello world!\n");
 sleep(1);
 /*子線程1在此退出*/
 return NULL;
}

/*子線程2入口函數(shù)*/
void *thread_routine2(void *arg)
{

 fprintf(stdout, "thread2: I'm running...\n");
 pthread_t main_thread = (pthread_t)arg;

 /*分離自我,不能再被連接*/
 pthread_detach(pthread_self());

 /*判斷主線程ID與子線程2ID是否相等*/
 if (!pthread_equal(main_thread, pthread_self())) {
  fprintf(stdout, "thread2: main thread id is not equal thread2\n");
 }

 /*等待主線程終止*/
 pthread_join(main_thread, NULL);
 fprintf(stdout, "thread2: main thread exit!\n");

 fprintf(stdout, "thread2: exit!\n");
 fprintf(stdout, "thread2: process exit!\n");
 /*子線程2在此終止,進(jìn)程退出*/
 pthread_exit(NULL);
}

int main(int argc, char *argv[])
{

 /*創(chuàng)建子線程1*/
 pthread_t t1;
 if (pthread_create(&t1, NULL, thread_routine1, NULL)!=0) {
  fprintf(stderr, "create thread fail.\n");
  exit(-1);
 }
 /*等待子線程1終止*/
 pthread_join(t1, NULL);
 fprintf(stdout, "main thread: thread1 terminated!\n\n");

 /*創(chuàng)建子線程2,并將主線程ID傳遞給子線程2*/
 pthread_t t2;
 if (pthread_create(&t2, NULL, thread_routine2, (void *)pthread_self())!=0) {
  fprintf(stderr, "create thread fail.\n");
  exit(-1);
 }

 fprintf(stdout, "main thread: sleeping...\n");
 sleep(3);
 /*主線程使用pthread_exit函數(shù)終止,進(jìn)程繼續(xù)存在*/
 fprintf(stdout, "main thread: exit!\n");
 pthread_exit(NULL); 

 fprintf(stdout, "main thread: never reach here!\n");
 return 0;
}

最終的執(zhí)行結(jié)果如下:

thread1: hello world!
main thread: thread1 terminated!

main thread: sleeping...
thread2: I'm running...
thread2: main thread id is not equal thread2
main thread: exit!
thread2: main thread exit!
thread2: exit!
thread2: process exit!

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Linux多線程編程的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!


網(wǎng)頁(yè)題目:Linux多線程編程的示例分析
本文地址:http://weahome.cn/article/gidihh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部