今天寫了4部分內容:
- 在線程和進程的基礎上,理解多線程是幹什麼的
- 相關函數
- 一個包含了2個線程的小例子
- 經常遇到的一個錯誤
一、首先,先來說幾點關於線程、進程、多線程的理解:
一個cpu有多個核,通常情況下一個核心對應一個線程,就可以提高程序運行效率。有篇文章是這麼比喻的:沒有線程的多核CPU 就像是 多個人在一個桌子上喫飯,有時候出現爭搶的情況 會降低效率。有多線程的多核CPU 就像是多個人在多個桌子上喫飯,都喫自己桌子上的菜 效率就很高很多。
- 線程是進程的一部分,一個進程可以有很多線程,每條線程同時並行執行不同的任務。
- 如果沒有進行顯式的線程分配,可以認爲進程是單線程的;如果進程中建立了線程,則可以認爲是多線程的
- 線程和進程的關係就像戲劇和劇本的關係。一個線程只能屬於一個進程,一個進程可以有多個線程
- 進程是進行系統分配的基本單位,線程所需資源需要共享
- 同一進程中的多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符和信號處理等等。但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。
二、下面再說關於線程的函數以及結構體
- pthread_t定義結構:
typedef struct
{
void * p; /* Pointer to actual object /
unsigned int x; / Extra information - reuse count etc */
} ptw32_handle_t;typedef ptw32_handle_t pthread_t;
- pthread_create()函數:
- pthread_join()函數:
爲什麼要使用pthread_join()?
在很多情況下,主線程生成並起動了子線程,如果子線程裏要進行大量的耗時的運算,主線程往往將於子線程之前結束,
但是如果主線程處理完其他的事務後,需要用到子線程的處理結果,也就是主線程需要等待子線程執行完成之後再結束,這個時候就要用到pthread_join()方法了。
即pthread_join()的作用可以這樣理解:主線程等待子線程的終止。也就是在子線程調用了pthread_join()方法後面的代碼,只有等到子線程結束了才能執行。
三、下面舉一個例子:
要求:寫兩個線程,一個線程每隔1s打印“線程1\n” 另外一個每隔5秒打印線程2\n。
5 #include<stdio.h>
6 #include<stdlib.h>
7 #include<pthread.h>
8
9 void * print1()
10 {
11 while(1)
12 {
13 sleep(1);
14 printf("線程1\n");
15 }
16 }
17
18 void * print2()
19 {
20 while(1)
21 {
22 sleep(5);
23 printf("線程2\n");
24 }
25 }
26
27 int main()
28 {
29 pthread_t th1,th2;
31
32 int pthd1 = pthread_create(&th1,NULL,print1,NULL);
33 if(pthd1 <0)
34 {
35 printf("fail to create pthread th1\n");
36 exit(1);
37 }
38
39 int pthd2 = pthread_create(&th2,NULL,print2,NULL);
40 if(pthd2 <0)
41 {
42 printf("fail to create pthread th2\n");
43 exit(1);
44 }
45
46 void * result;
47 if(pthread_join(th1, &result) == -1){
48 puts("fail to recollect th1");
49 exit(1);
50 }
51
52 if(pthread_join(th2, &result) == -1){
53 puts("fail to recollect th2");
54 exit(1);
55 }
56
57 return 0;
58 }
四、寫多線程的時候經常遇到這樣一個問題,編譯之後提醒錯誤:thread.c:(.text+0xd8): undefined reference to `pthread_join’ ,頭文件也包含了就是編譯不過,原因和解決辦法是什麼呢?
原因:
網上查找了資料發現pthread 庫不是 Linux 系統默認的庫,連接時需要使用靜態庫 libpthread.a.
問題解決如下:
在編譯中要加 -lpthread參數:
arm-none-linux-gnueabi-gcc -o pthread pthread.c -static -lpthread