溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

多線程pthread_create()函數(shù)的用法

發(fā)布時間:2021-07-13 10:41:01 來源:億速云 閱讀:201 作者:chen 欄目:互聯(lián)網(wǎng)科技

這篇文章主要講解了“多線程pthread_create()函數(shù)的用法”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“多線程pthread_create()函數(shù)的用法”吧!

總述:pthread_create是(Unix、Linux、Mac OS X)等操作系統(tǒng)的創(chuàng)建線程的函數(shù)。它的功能是創(chuàng)建線程(實際上就是確定調(diào)用該線程函數(shù)的入口點),在線程創(chuàng)建以后,就開始運行相關(guān)的線程函數(shù)。
pthread_create的返回值表示成功,返回0;表示出錯,返回表示-1。

pthread_create函數(shù)如何創(chuàng)造線程
函數(shù)原型聲明:

#include <pthread.h>
int pthread_create(
                 pthread_t *restrict tidp,   //新創(chuàng)建的線程ID指向的內(nèi)存單元。
                 const pthread_attr_t *restrict attr,  //線程屬性,默認為NULL
                 void *(*start_rtn)(void *), //新創(chuàng)建的線程從start_rtn函數(shù)的地址開始運行
                 void *restrict arg //默認為NULL。若上述函數(shù)需要參數(shù),將參數(shù)放入結(jié)構(gòu)中并將地址作為arg傳入。
                  );

1.傳遞參數(shù)注意的問題
問題:
避免直接在傳遞的參數(shù)中傳遞發(fā)生改變的量,否則會導(dǎo)致結(jié)果不可測。
即使是只再創(chuàng)造一個單線程,也可能在線程未獲取傳遞參數(shù)時,線程獲取的變量值已經(jīng)被主線程進行了修改。

通常解決方案:
重新申請一塊內(nèi)存,存入需要傳遞的參數(shù),再將這個地址作為arg傳入。

2.使用時注意防止內(nèi)存泄漏
在默認情況下通過pthread_create函數(shù)創(chuàng)建的線程是非分離屬性的,由pthread_create函數(shù)的第二個參數(shù)決定,在非分離的情況下,當(dāng)一個線程結(jié)束的時候,它所占用的系統(tǒng)資源并沒有完全真正的釋放,也沒有真正終止。

只有在pthread_join函數(shù)返回時,該線程才會釋放自己的資源。
或者是設(shè)置在分離屬性的情況下,一個線程結(jié)束會立即釋放它所占用的資源。

如果要保證創(chuàng)建線程之后,確保無內(nèi)存泄漏,必須采用如下方法來規(guī)范pthread_create的使用:

1. 設(shè)置線程是detached(分離屬性的)
void run() { 
    return;

int main(){ 
    pthread_t thread; 
    pthread_attr_t attr; 
    pthread_attr_init( &attr ); 
    pthread_attr_setdetachstate(&attr,1); 
    pthread_create(&thread, &attr, run, 0); //第二個參數(shù)決定了分離屬性

    //...... 
    return 0; 
}

但是,在博客:https://blog.csdn.net/qiurisuixiang/article/details/6648213評論中,有人提到:


2. 配套使用pthread_join函數(shù)
pthread_join()函數(shù)會一直阻塞調(diào)用線程,直到指定的線程終止。當(dāng)pthread_join()返回之后,應(yīng)用程序可回收與已終止線程關(guān)聯(lián)的任何數(shù)據(jù)存儲空間。
但是,同時需要注意,一定要和上面創(chuàng)建的某一線程配套使用,這樣還可以起到互斥的作用。否則多線程可能搶占CPU資源,導(dǎo)致運行結(jié)果不確定。

??鸵坏李}目: 下面程序輸出結(jié)果是什么?(不能確定)

#include<stdio.h>
#include<string.h>
#include <pthread.h>

void* print1(void* data){
    printf("1 ");
}

void* print2(void* data){
    printf("2 ");
}

void* print3(void* data){
    printf("3 ");
}

int main(void){
    pthread_t t,t1,t2;

    pthread_create(&t,0,print1,NULL);
    pthread_create(&t1,0,print2,NULL);
    pthread_create(&t2,0,print3,NULL);

    pthread_join(t,NULL);
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
    printf("\n");
}

分析:
在pthread_join()之前,3個線程都已提交,它們可能都已經(jīng)順序隨機地執(zhí)行了,也可能沒有,所以結(jié)果也是不可預(yù)測的。不過這樣也可以起到回收內(nèi)存的作用吧?

//這樣才是按順序的。
pthread_create(&t, 0, print1, NULL);
pthread_join(t, NULL);
pthread_create(&t1, 0, print2, NULL);
pthread_join(t1, NULL);
pthread_create(&t2, 0, print3, NULL);
pthread_join(t2, NULL);

補充:pthread_join()函數(shù)
函數(shù)原型:

int pthread_join(
               pthread_t tid, //需要等待的線程,指定的線程必須位于當(dāng)前的進程中,而且不得是分離線程
               void **status  //線程tid所執(zhí)行的函數(shù)返回值(返回值地址需要保證有效),其中status可以為NULL
                 );

pthread非linux系統(tǒng)的默認庫, 需手動鏈接-線程庫 -lpthread

返回值:
調(diào)用成功返回0.
ESRCH
描述: 沒有找到與給定的線程ID 相對應(yīng)的線程。(如果多個線程等待同一個線程終止,則所有等待線程將一直等到目標線程終止。然后一個等待線程成功返回。其余的等待線程將失敗返回ESRCH錯誤)
EDEADLK
描述: 將出現(xiàn)死鎖,如一個線程等待其本身,或者線程A和線程B 互相等待。
EINVAL
描述: 與給定的線程ID相對應(yīng)的線程是分離線程。

感謝各位的閱讀,以上就是“多線程pthread_create()函數(shù)的用法”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對多線程pthread_create()函數(shù)的用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI