【Linux 編程】線程編程

來源:互聯網
上載者:User

  一個進程中可以包含多個線程。線程中包含了表示進程執行環境必須的資訊,其中包括進程中標識線程的線程ID、一組寄存器值、棧、調度 優先順序和策略、訊號屏蔽字、errno變數以及線程私人資料。進程的所有資訊對該進程的所有線程都是共用的,包括可執行檔程式文本、程式的全域記憶體和堆記憶體、棧以及檔案描述符。

  需要注意的是,進程ID是全域唯一的,但是線程ID只有在它所屬的進程環境中有效。

  通過調用函數pthread_create來建立線程(更多內容:man 3 pthread_create):

1 #include <pthread.h>2 3 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);4 5 // Compile and link with -pthread

View Code

  其中,參數arg作為線程開始函數start_routine的傳遞參數。若傳遞參數不止一個,則將這些參數放在一個結構體中,然後把這個結構的地址作為arg參數傳入。

  注意,線程建立時並不能保證哪個線程會先運行:是新建立的線程還是調用線程。

  若進程中任一線程調用exit,_Exit或_exit,那麼整個進程會終止。在不終止整個進程的情況下停止它的控制流程,單個線程可以通過以下三種方式退出:

  1. 線程從start_routine中返回,則傳回值就是線程的退出碼;
  2. 線程可以被同一進程中的其他線程利用函數pthread_cancel函數來取消;
  3. 線程在start_routine中調用pthread_exit。

  同一進程中的其他線程可以通過函數pthread_join來擷取指定線程的退出碼(man 3 pthread_join)。若該函數第二個參數設定為NULL,則pthread_join函數將等待指定線程終止。在預設情況下,線程的之中狀態會儲存到對該線程調用pthread_join,如果線程已經處於分離狀態,線程的底層儲存資源可以線上程終止時立即被收回。當線程被分離時,並不能用pthread_join函數等待它的終止狀態。

  同一進程中的其他線程可以調用函數pthread_cancel來請求取消同一進程中的其他線程。

  函數pthread_detach可以用於使線程進入分離狀態。

  例子(來自pthread_create的linux說明文檔):

  1 #include <pthread.h>  2 #include <string.h>  3 #include <stdio.h>  4 #include <stdlib.h>  5 #include <unistd.h>  6 #include <errno.h>  7 #include <ctype.h>  8   9 #define handle_error_en(en, msg) \ 10                do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) 11  12 #define handle_error(msg) \ 13                do { perror(msg); exit(EXIT_FAILURE); } while (0) 14  15 struct thread_info      /* Used as argument to thread_start() */ 16 { 17     pthread_t thread_id;        /* ID returned by pthread_create() */ 18     int       thread_num;       /* Application-defined thread # */ 19     char     *argv_string;      /* From command-line argument */ 20 }; 21  22 /* Thread start function: display address near top of our stack, 23    and return upper-cased copy of argv_string */ 24  25 static void * 26 thread_start(void *arg) 27 { 28     struct thread_info *tinfo = (struct thread_info *) arg; 29     char *uargv, *p; 30  31     printf("Thread %d: top of stack near %p; argv_string=%s\n", 32            tinfo->thread_num, &p, tinfo->argv_string); 33  34     uargv = strdup(tinfo->argv_string); 35     if (uargv == NULL) 36         handle_error("strdup"); 37  38     for (p = uargv; *p != '\0'; p++) 39         *p = toupper(*p); 40  41     return uargv; 42 } 43  44 int 45 main(int argc, char *argv[]) 46 { 47     int s, tnum, opt, num_threads; 48     struct thread_info *tinfo; 49     pthread_attr_t attr; 50     int stack_size; 51     void *res; 52  53     /* The "-s" option specifies a stack size for our threads */ 54  55     stack_size = -1; 56     while ((opt = getopt(argc, argv, "s:")) != -1) 57     { 58         switch (opt) 59         { 60         case 's': 61             stack_size = strtoul(optarg, NULL, 0); 62             break; 63  64         default: 65             fprintf(stderr, "Usage: %s [-s stack-size] arg...\n", 66                     argv[0]); 67             exit(EXIT_FAILURE); 68         } 69     } 70  71     num_threads = argc - optind; 72  73     /* Initialize thread creation attributes */ 74  75     s = pthread_attr_init(&attr); 76     if (s != 0) 77         handle_error_en(s, "pthread_attr_init"); 78  79     if (stack_size > 0) 80     { 81         s = pthread_attr_setstacksize(&attr, stack_size); 82         if (s != 0) 83             handle_error_en(s, "pthread_attr_setstacksize"); 84     } 85  86     /* Allocate memory for pthread_create() arguments */ 87  88     tinfo = calloc(num_threads, sizeof(struct thread_info)); 89     if (tinfo == NULL) 90         handle_error("calloc"); 91  92     /* Create one thread for each command-line argument */ 93  94     for (tnum = 0; tnum < num_threads; tnum++) 95     { 96         tinfo[tnum].thread_num = tnum + 1; 97         tinfo[tnum].argv_string = argv[optind + tnum]; 98  99         /* The pthread_create() call stores the thread ID into100            corresponding element of tinfo[] */101 102         s = pthread_create(&tinfo[tnum].thread_id, &attr,103                            &thread_start, &tinfo[tnum]);104         if (s != 0)105             handle_error_en(s, "pthread_create");106     }107 108     /* Destroy the thread attributes object, since it is no109        longer needed */110 111     s = pthread_attr_destroy(&attr);112     if (s != 0)113         handle_error_en(s, "pthread_attr_destroy");114 115     /* Now join with each thread, and display its returned value */116 117     for (tnum = 0; tnum < num_threads; tnum++)118     {119         s = pthread_join(tinfo[tnum].thread_id, &res);120         if (s != 0)121             handle_error_en(s, "pthread_join");122 123         printf("Joined with thread %d; returned value was %s\n",124                tinfo[tnum].thread_num, (char *) res);125         free(res);      /* Free memory allocated by thread */126     }127 128     free(tinfo);129     exit(EXIT_SUCCESS);130 }

View Code

  運行結果

  

相關文章

聯繫我們

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