Linux作業系統分析(9)- 多線程和安全執行緒

來源:互聯網
上載者:User

進程和線程

         進程是作業系統的概念,每當我們執行一個程式時,對於作業系統來講就建立了一個進程,在這個過程中,伴隨著資源的分配和釋放。可以認為進程是一個程式的一次執行過程。

         線程是進程內的一個相對獨立的可執行檔單元。若把進程稱為任務的話,那麼線程則是應用中的一個子任務的執行。

        線程和進程十分相似,不同的只是線程比進程小。首先,線程採用了多個線程可共用資源的設計思想;例如,它們的操作大部分都是在同一地址空間進行的。其次,從一個線程切換到另一線程所花費的代價比進程低。再次,進程本身的資訊在記憶體中佔用的空間比線程大,因此線程更能允分地利用記憶體。


多線程例子

        使用Pthreads的主要動機是提高潛在程式的效能。 當與建立和管理進程的花費相比,線程可以使用作業系統較少的開銷,管理線程需要較少的系統資源。

        Pthreads定義了一套C語言的類型、函數與常量,它以pthread.h標頭檔和一個線程庫實現。

      

#include <pthread.h> #include <stdio.h> #define NUM_THREADS     5  void *PrintHello(void *threadid) {    int tid;    tid = (int)threadid;    printf("Hello World! It's me, thread #%d!\n", tid);    pthread_exit(NULL); }  int main (int argc, char *argv[]) {    pthread_t threads[NUM_THREADS];    int rc, t;    for(t=0; t<NUM_THREADS; t++){       printf("In main: creating thread %d\n", t);       rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);       if (rc){          printf("ERROR; return code from pthread_create() is %d\n", rc);          return -1;       }    }    pthread_exit(NULL); } 

     

代碼一行行解釋。

#1 包含pthread標頭檔,這個在linux中預設就有,無需配置安裝。

#5 -11 定義線程函數,作為後面pthread_create的參數,pthread_exit()為終止當前線程。

#15 定義一個線程控制代碼數組。

#17-24 建立5個線程。

pthread_create參數:
thread:返回一個不透明的,唯一的新線程標識符。
attr:不透明的線程屬性對象。可以指定一個線程屬性對象,或者NULL為預設值。
start_routine:線程將會執行一次的C函數。
arg: 傳遞給start_routine單個參數,傳遞時必須轉換成指向void的指標類型。沒有參數傳遞時,可設定為NULL。


pthread_create()函數允許程式員想線程的start routine傳遞一個參數。當多個參數需要被傳遞時,可以通過定義一個結構體包含所有要傳的參數,然後用pthread_create()傳遞一個指向改結構體的指標,來打破傳遞參數的個數的限制。
所有參數都應該傳引用傳遞並轉化成(void*)。


安全執行緒

安全執行緒問題都是由全域變數及靜態變數引起的。

若每個線程中對全域變數、靜態變數只有讀操作,而無寫操作,一般來說,這個全域變數是安全執行緒的;若有多個線程同時執行寫操作,一般都需要考慮線程同步,否則的話就可能影響安全執行緒。

看一個向量點乘的例子:


#include <pthread.h> #include <stdio.h> #include <malloc.h>#define NUM_THREADS  5 #define VECLEN 100typedef struct{double *a;double *b;double sum;int veclen;}DotData;pthread_t threads[NUM_THREADS];pthread_mutex_t mutexsum;DotData dotstr; void *dotproduct(void *arg) { int i,start,end,offset,len;double mysum, *x, *y;offset = (int)arg;len = dotstr.veclen;start = offset*len;end = start + len;x = dotstr.a;y = dotstr.b;mysum = 0;for(i=start; i<end; i++){mysum += (x[i] * y[i]);}pthread_mutex_lock(&mutexsum);dotstr.sum += mysum;printf("mysum%d:%f\n",(int)arg,mysum);pthread_mutex_unlock(&mutexsum);pthread_exit(NULL);}  int main (int argc, char *argv[]) { int i;double *a,*b;void *status;pthread_attr_t attr;a = (double*)malloc(NUM_THREADS*VECLEN*sizeof(double));b = (double*)malloc(NUM_THREADS*VECLEN*sizeof(double));for(i=0; i<NUM_THREADS*VECLEN; i++){a[i] = 2.0;b[i] = a[i];}dotstr.veclen = VECLEN;dotstr.a = a;dotstr.b = b;dotstr.sum = 0;pthread_mutex_init(&mutexsum,NULL);pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);for(i=0; i<NUM_THREADS; i++){pthread_create(&threads[i],&attr,dotproduct,(void*)i);}pthread_attr_destroy(&attr);for(i=0; i<NUM_THREADS; i++){pthread_join(threads[i],&status);}printf("Sum = %f\n",dotstr.sum);free(a);free(b);pthread_mutex_destroy(&mutexsum);   pthread_exit(NULL); } 



         在上面的代碼中,將兩個向量的點乘分別放到5個線程裡分塊完成,理想的情況下,計算速度提升了5倍。

        在dotproduct函數中,操作dotstr的時候,使用了互斥鎖。首先開啟互斥 pthread_mutex_lock(&mutexsum),然後操作資料,最後開啟互斥pthread_mutex_unlock(&mutexsum)。雖然在這裡添不添加互斥沒有關係,但如果對全域變數的操作更加複雜的時候,比如有乘除法的時候,互斥鎖就變得很重要了。

        在main函數中,pthread_attr_t表示線程屬性結構體,使用的時候需要對此結構體進行初始化,初始化後使用,使用後還要進行去除初始化。pthread_attr_init:初始化,pthread_attr_destory:去除初始化。

        設定線程分離狀態的函數為pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)。第二個參數可選為PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程)。

            pthread_join()函數,以阻塞的方式等待thread指定的線程結束。當函數返回時,被等待線程的資源被收回。如果進程已經結束,那麼該函數會立即返回。並且thread指定的線程必須是joinable的。


參考

pthreads 的基本用法 - http://www.ibm.com/developerworks/cn/linux/l-pthred/

POSIX 多線程程式設計  - http://www.cnblogs.com/mywolrd/archive/2009/02/05/1930707.html


相關文章

聯繫我們

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