Linux--線程基本概念及線程分離__Linux

來源:互聯網
上載者:User

線程:

一.什麼是線程(tcb)。

線程是在進程地址空間內啟動並執行,強調資源共用(多個線程共用一份地址空間)。Linux下是用進程類比線程,並無真正的線程。進程是分配資源的基本單位,線程是調度的基本單位。


二.線程可以共用和獨佔。

共用的:

1. 檔案描述符表

2. 每種訊號的處理方式(SIG_IGN、SIG_DFL或者自訂的訊號處理函數)

3. 當前工作目錄

4. 使用者id和組id

獨佔的:

1.      線程id

2.      上下文,包括各種寄存器的值,程式計數器和指標。

3.      棧空間

4.      訊號屏蔽字

5.      調度優先順序

 

三.線程的操作(遵守posix標準)

線程建立:

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

傳回值:成功返回0,失敗返回錯誤碼

pthread_t *thread:線程id,只在使用者區有效,建立並且附過來。

pthread_attr_t *attr:一般為NULL,設定線程屬性。

void *(*start_routine) (void *):函數指標,調用後執行此函數中的代碼。

void *arg:為第三個參數的參數。一般為NULL。

 

         線程終止:

void pthread_exit(void *retval);

參數:reval是void*類型的,和線程函數傳回值的用法一樣,其他線程可以調用pthread_join獲得這個指標。pthread_exit或return返回的指標所指向的單元必須是全域或用malloc分配的,不能線上程函數的棧上分配,因為其他線程得到這個返回指標時線程已經退出。

 

         線程取消:

int  pthread_cancel(pthread_t  thread);

傳回值:成功返回0,失敗返回錯誤碼。

 

         線程等待:

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

調用該函數的線程將掛起等待,直到id為thread的線程終止。thread線程以不同的.方法終止,通過pthread_join得到的終止狀態是不同的,總結如下:

1. 如果thread線程通過return返回,value_ptr所指向的單元裡存放的是thread線程函數的傳回值。

2. 如果thread線程被別的線程調用pthread_cancel異常終掉,value_ptr所指向的單元裡存放的是常數PTHREAD_CANCELED。

3. 如果thread線程是自己調用pthread_exit終止的.value_ptr所指向的單元存放的是傳給pthread_exit的參數。 如果對thread線程的終止狀態不感興趣,可以傳NULL給value_ptr參數。

 

下面驗證線程退出時的狀態

void * thread_run1(void *arg){       printf("thread_run1 : tid:%lu pid:%d \n",pthread_self(),getpid());       return ((void*)1);} void * thread_run2(void *arg){       printf("thread_run2 : tid:%lu pid:%d\n",pthread_self(),getpid());       pthread_exit((void*)2);       return ((void*)1);} void * thread_run3(void *arg){       while(1)       {                printf("thread_run3 :tid:%lu pid:%d \n",pthread_self(),getpid());                sleep(1);       }       return NULL;}int main(){       pthread_t id;       void *temp;       //正常退出時候查看他的id以及傳回值        pthread_create(&id,NULL,thread_run1,NULL);       pthread_join(id,&temp);       printf("thread_run1 return:id %u return code%d\n",id,(int)temp);        //當中間調用線程終止的時候       pthread_create(&id,NULL,thread_run2,NULL);       pthread_join(id,&temp);       printf("thread_run2 return:id %u return code%d\n",id,(int)temp);        //當線程死迴圈時用函數取消線程的時候       pthread_create(&id,NULL,thread_run3,NULL);       sleep(1);       pthread_cancel(id);       pthread_join(id,&temp);       printf("thread_run3 return:id %u return code%d\n",id,(int)temp);        printf("the main tid is %u pid %d\n",pthread_self(),getpid());       return 0;}


運行結果:

 

線程與分離與結合:

在任何一個時間點上,線程是可結合的(joinable)或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死。在被其他線程回收之前,它的儲存空間資源(例如棧)是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的儲存空間資源在它終止時由系統自動釋放。

 

建立出的線程預設屬性為可結合,所以必須等待它否則會產生類似殭屍進程的情況。

若線程為可分離則不需要join,線程運行結束後會自動釋放所有資源。

 

驗證分離的線程是否能被join等待

void *thread_run(void * arg){        pthread_detach(pthread_self());        printf("%s\n",(char*)arg);        return NULL;} int main(){        pthread_t id;        int temp =pthread_create(&id,NULL,thread_run,"thread1 run\n");        if(temp != 0)        {                printf("create errorcode:%s\n",strerror(temp));                return -1;        }        //一個分離的線程是不能被其他進程殺死或回收的 所以最後回收失敗        int ret = 0;        sleep(2);        if(0 == pthread_join(id,NULL))        {                printf("thread waitsuccess\n");                ret = 0;        }        else {                printf("thread waitfailed\n");                ret = 1;        }                return ret;}

 

線程的同步與互斥(相當於一把鎖,二元訊號量):

初始化:pthread_mutex_t  mutex_lock =  PTHREAD_MUTEX_INITIALIZER 

上鎖:pthread_mutex_t_lock(&mutex_lock);

解鎖:pthread_mutex_t_unlock(&mutex_lock);

 

如果沒有加鎖與去鎖

當同時執行四個線程的時候 加出來最後的結果不一定為我們想要得到的值 因為會發生資料不一致問題。

當我們加鎖之後 數值就會一致

pthread_mutex_t mx= PTHREAD_MUTEX_INITIALIZER;static int g_count= 0;void *read_write_mem(void * _val){        int val = 0;        int i = 0;        for(;i<5000;++i)        {                pthread_mutex_lock(&mx);                val = g_count;                printf("pthread idis:%x,count is:%d \n",pthread_self(),g_count);                g_count = val+1;                pthread_mutex_unlock(&mx);        }return  NULL;} int main(){        pthread_t tid1;        pthread_t tid2;        pthread_t tid3;        pthread_t tid4;        pthread_create(&tid1,NULL,read_write_mem,NULL);        pthread_create(&tid2,NULL,read_write_mem,NULL);pthread_create(&tid3,NULL,read_write_mem,NULL);pthread_create(&tid4,NULL,read_write_mem,NULL);        pthread_join(tid1,NULL);        pthread_join(tid2,NULL);        pthread_join(tid3,NULL);        pthread_join(tid4,NULL);        printf("count val is%d\n",g_count);        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.