linux系統編程:線程原語

來源:互聯網
上載者:User

標籤:線程   linux   pthread_exit   pthread_cancel   pthread_create   

                                 線程原語

線程概念

   線程(thread),有時被稱為輕量級進程(Lightweight Process,LWP),是程式執行流的最小單元。一個標準的線程由線程ID,當前指令指標(PC),寄存器集合和堆棧組成。更多詳細解釋看百度百科:線程。

在Linux shell下通過命令 $ ps -Lf pid 查看指定pid號下的所有線程。


線程之間的共用與非共用

這裡的線程是指同一進程下的線程。

共用:

   1.檔案描述符表
   2.每種訊號的處理方式
   3.當前工作目錄
   4.使用者ID和組ID
   5.記憶體位址空間

非共用:

   1.線程id
   2.處理器現場和棧指標(核心棧)
   3.獨立的棧空間(使用者空間棧)
   4.errno變數
   5.訊號屏蔽字
   6.調度優先順序


線程原語

通過命令 $ man -k pthread 查看系統下與線程有關的所有函數。

一般的,把main函數稱作主線程或主控線程,其它線程都稱作是子線程。

建立線程

#include<pthread.h>int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

pthread_t *thread:傳遞一個pthread_t變數地址進來,用於儲存新線程的tid(線程ID)

const pthread_attr_t *attr:線程屬性設定,如使用預設屬性,則傳NULL

void *(*start_routine)(void *):函數指標,指向新線程應該載入執行的函數模組

void *arg:指定線程將要載入調用的那個函數的參數

傳回值:成功返回0,失敗返回錯誤號碼。以前學過的系統函數都是成功返回0,失敗返回-1,而錯誤號碼儲存在全域變數errno中,而pthread庫的函數都是通過傳回值返回錯誤號碼,雖然每個線程也都有一個errno,但這是為了相容其它函數介面而提供的,pthread庫本身並不使用它,通過傳回值返回錯誤碼更加清晰。
Compile and link with -lpthread.
typedef unsigned long int pthread_t;   //在不同的系統中pthread_t可能會有不同的實現


結束線程

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

1.return。這種方法對主控線程不適用,從main函數return相當於調用exit。

2.一個線程可以調用pthread_cancel終止同一進程中的另一個線程。

#include <pthread.h>int pthread_cancel(pthread_t thread);
被取消的線程,退出值,定義在Linux的pthread庫中常數PTHREAD_CANCELED的值是-1。可以在標頭檔pthread.h中找到它的定義:#define PTHREAD_CANCELED ((void *) -1)。也就是說,被pthread_cancel結束的線程,退出值,都是-1。

同一進程的線程間,pthread_cancel向另一線程發終止訊號。系統並不會馬上關閉被取消線程,只有在被取消線程下次系統調用時,才會真正結束線程。或調用pthread_testcancel,讓核心去檢測是否需要取消當前線程。

3.線程可以調用pthread_exit終止自己。

#include <pthread.h>void pthread_exit(void *retval);void *retval:線程退出時傳遞出的參數,可以是退出值或地址,如是地址時,不能是線程內部申請的局部地址。
       

在任何地方調用exit,都會使整個進程退出。


線程id
#include <pthread.h>pthread_t pthread_self(void);RETURN VALUEThis function always succeeds, returning the calling thread’s ID.
線上程中使用pthread_self,擷取線程id。


回收線程
#include <pthread.h>int pthread_join(pthread_t thread, void **retval);pthread_t thread:回收線程的tidvoid **retval:接收退出線程傳遞出的傳回值傳回值:成功返回0,失敗返回錯誤號碼
同進程類似,線程退出後,同樣需要進行回收,所以pthread_join類似於wait。調用該函數的線程將掛起等待,直到id為thread的線程終止。thread線程以不同的方法終止,通過pthread_join得到的終止狀態是不同的,總結如下:
  1. 如果thread線程通過return返回,retval所指向的單元裡存放的是thread線程函數的傳回值。
  2. 如果thread線程被別的線程調用pthread_cancel異常終止掉,retval所指向的單元裡存放的是常數PTHREAD_CANCELED。
  3. 如果thread線程是自己調用pthread_exit終止的,retval所指向的單元存放的是傳給pthread_exit的參數。
如果對thread線程的終止狀態不感興趣,可以傳NULL給retval參數。


程式碼範例使用return和pthread_exit結束進程
//thread_exit.c#include <stdio.h>#include <unistd.h>#include <pthread.h>void *fun_1(void *argv){printf("Hello %s,my thread id is %x\n", (char*)argv, pthread_self());sleep(1);//pthread_exit((void*)1);return (void*)1;}void *fun_2(void *argv){printf("Hello %c, my thread id is %x\n", (char)argv, pthread_self());sleep(2);pthread_exit((void*)"David");}int main(void){int *ret1;char *ret2;pthread_t tid1, tid2;pthread_create(&tid1, NULL, fun_1, (void*)"zhangxiang");pthread_create(&tid2, NULL, fun_2, (void*)‘D‘);pthread_join(tid1, (void*)&ret1);pthread_join(tid2, (void*)&ret2);printf("thread %x exit with %x\n", tid1, ret1);printf("thread %x exit with %s\n", tid2, ret2);return 0;}$ gcc thread_exit.c -lpthread$ ./a.outHello D, my thread id is 745e9700Hello zhangxiang, my thread id is 74fea700thread 74fea700 exit with 1thread 745e9700 exit with David
       

使用pthread_cancel終止另一個線程
//thread_cancel.c#include <stdio.h>#include <pthread.h>void *fun(void *argv){printf("thread %x running\n", pthread_self());pthread_exit((void*)0);}int main(void){pthread_t tid;void *ret;pthread_create(&tid, NULL, fun, NULL);pthread_join(tid, &ret);printf("thread %x exit with %d\n", tid, (int)ret);pthread_create(&tid, NULL, fun, NULL);pthread_cancel(tid);pthread_join(tid, &ret);printf("thread %x exit with %d\n", tid, (int)ret);return 0;}$ gcc thread_cancel.c -lpthread$ a.outthread 96da9700 runningthread 96da9700 exit with 0thread 96da9700 runningthread 96da9700 exit with -1


既可以在主線程中使用pthread_cancel終止子線程,也可以在子線程中終止另一個子線程。




CCPP Blog 目錄


著作權聲明:本文為博主原創文章,轉載,請註明出處。

linux系統編程:線程原語

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.