Linux下線程的概念和使用__Linux

來源:互聯網
上載者:User

一. 概念
  首先Linux並不存在真正的線程,Linux的線程是使用進程類比的。當我們需要在一個進程中同時運行多個執行流時,我們並不可以開闢多個進程執行我們的操作(32位機器裡每個進程認為它 獨享 4G的記憶體資源),此時便引入了線程,例如當我們既需要下載內容,又需要瀏覽網頁時,此時多線程便起了作用。線程是承擔調度的基本單位,一個進程可擁有多個線程,它的執行力度比進程更加細緻,線程資源共用。
二. 特點
  由於同一進程的多個線程共用同一地址空間,所以程式碼片段,資料區段是共用的,如果定義一個函數(儲存在程式碼片段),各線程都可以進行調用,如果定義個全域變數(儲存在資料區段),在各線程中都可以訪問到,除此之外,各線程還共用以下進程資源和環境:
1.檔案描述符表
2.每種訊號的處理方式(SIG_IGN,SIG_DFL,使用者自訂)
3.當前工作目錄
4.使用者id和組id
但有些資源是線程獨享的:
1.線程id
2.上下文,包括各種寄存器的值,程式計數器和棧指標
3.棧空間
4.errno變數
5.訊號屏蔽字
6.調度優先順序
三. 線程的簡單實用
1.建立線程

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

  傳回值:成功返回0,失敗返回錯誤號碼。在一個線程中調pthread_create()建立新的線程後,當前線程從pthread_create()返回繼續往下執行,新的線程所執行的代碼由我們傳給pthread_create的函數指標start_routine決定。
  thread參數傳入線程的id,void ( star_routine)(void )由使用者進行撰寫。
2.線程終止
  void pthread_exit(void *retval)函數用於進程終止,傳入一個id,調用exit()的話,主進程會終止。終止線程由三種方法:
1).從線程函數return。這種方法法對主線程不適用,從main函數return相當於調用exit。
2).一個線程可以調用pthread_cancel終止同一進程中的另一個線程。
3).線程可以調pthread_exit終自己。
  retval是void *類型,其它線程可以調pthread_join獲得這個指標。
3.線程等待
  int pthread_join(pthread_t thread,void **retval);成功返回0,失敗返回錯誤號碼。 線程的等待是以阻塞式等待,線程不等待會產生記憶體泄露(類似進程的殭屍進程)
4.進程取消
  在合理範圍內,線程可以自我或者被別人取消。取消後返回PTHREAD_CANCELED(它被定義為(void *)-1),取消調用函數pthread_cancel(id);
5.線程分離
  在任何一個時間點上線程是可結合的(joinable)或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死。在被其他線程回收之前,它的儲存空間資源(例如棧)是不釋放的。相反一個分離的線程是不能被其他線程回收或殺死的,它的儲存空間資源在它終時時由系統自動釋放。
  預設情況一個線程是可結合的,每一個可結合的線程都應該被顯性的回收,既調用pthread_join()函數,分離調用函數pthread_detach。分離的這個函數是非阻塞的,可以立即返回。但為什麼要分離呢。因為主進程在處理線程時,要處理不止一個,而每一個都需要被等待,然而join是阻塞式的,這樣的話就只能處理一個線程,所以要加入分離,這樣就可以處理多個線程。調用pthread_detach()後,這些子進程的狀態會被設定為分離的,該線程運行結束會自動釋放所有資源。
  下面為測試代碼:

#include <stdio.h>#include <stdlib.h>#include <pthread.h>void* thread1(){    pthread_detach(pthread_self());//分離後仍可被等待    printf("pid is: %d, tid is: %d\n", getpid(),pthread_self());    return (void*)1;}int main(){    pthread_t tid;    void *ret;    int err = pthread_create(&tid, NULL, thread1, NULL);    if (err != 0)    {        perror("pthread_create\n");        return err;    }    //如果直接運行等待代碼,一般會等待成功,返回1    //如果在等待之前加入取消。等待錯誤,返回-1    //  pthread_cancel(tid);    //線程可以自我取消也可以被取消,線程終止    //調用pthread_exit(tid);和取消同樣用法。    int tmp = pthread_join(tid, &ret);    if (tmp == 0)    {        printf("wait success\n");    }    else    {        printf("wait failed\n");    }    printf(" pid is: %d, tid is: %d\n", getpid(),pthread_self());    sleep(1);    return 0;}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.