線程筆記

學習筆記(三)之線程:

進程創建,進程的調度較爲消耗硬件資源,進程切換時會涉及到多個硬件資源的切換c++


線程本質是帶有時間片的函數(模塊化代碼,多個函數相對獨立)編程


線程共享資源:
共享進程空間0~3G空間
PIDide

線程獨立的資源:
線程的棧區獨立
PC指針
線程errno獨立
線程編號相互獨立模塊化

注:不能返回線程空間內的地址函數

安裝線程庫:
sudo apt-get install manpages-posix-dev
sudo apt-get install manpages-posixpost

線程編程:
注:
1.添加#include <pthread.h>
2.編譯時連接線程庫 -lpthread
3.線程中慎用exit函數學習

線程建立:本質是線程調用
pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
參數:1.pthread_create成功執行時能夠獲取線程編號 準備pthread_t 變量 取地址放入;2.線程屬性設置 填NULL表示默認屬性
3.被調用的線程函數的入口地址 void * 線程名(void *);4.用於給第三個參數傳參 不須要填NULL
功能:線程調用函數
返回值:成功返回0,失敗返回錯誤號,並設置errno號ui

線程阻塞函數 相似進程中的waitpid(pid)
pthread_join
int pthread_join(pthread_t thread, void **retval);
功能:阻塞等待指定線程退出
參數:1.線程號 2.接收pthread_exit返回的信息 定義一個void* p &p放入,不關心填NULL
返回值:成功返貨0,失敗返回errno號spa

線程退出 相似進程中的exit
pthread_exit
void pthread_exit(void *retval);
功能:結束調用的線程,返回的一個地址(用於記錄信息的首地址,不使用填NULL)線程

線程取消
pthread_cancel
int pthread_cancel(pthread_t thread);
功能:將指定線程退出

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 int i = 0;
 6 int a,b;
 7 
 8 
 9 void *fun_a(void *arg)
10 {
11     while(1)
12     {
13         i++;
14         a = i;
15         b = a;
16     }
17     pthread_exit(NULL);
18 }
19 
20 void *fun_b(void *arg)
21 {
22     while(1)
23     {
24         if(a != b)
25         {
26             printf("i:%d a:%d b:%d\n",i,a,b);
27         }
28     }
29     pthread_exit(NULL);
30 }
31 
32 int main(int argc, const char *argv[])
33 {
34     int ret = 0;
35     ret = pthread_create(&tid1,NULL,fun_a,NULL);
36     if(ret != 0)
37     {
38         fprintf(stderr,"fail to create pthread1:%d\n",ret);
39         exit(1);
40     }
41     pthread_create(&tid2,NULL,fun_b,NULL);
42 
43 
44     pthread_join(tid1,NULL);
45     pthread_join(tid2,NULL);
46 
47     return 0;
48 }
pthread1
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 
 4 pthread_t tid1,tid2;
 5 
 6 //線程A:
 7 void *fun1(void * arg)
 8 {
 9     if(arg != NULL)
10     {
11         printf("pthread1_arg:%s\n",(char *)arg);
12     }
13     printf("i'm pthread_1!\n");
14     pthread_exit("hehehe");
15 }
16 
17 
18 //線程B:
19 void *fun2(void * arg)
20 { 
21     if(arg != NULL)
22     {
23         printf("pthread2_arg:%s\n",(char *)arg);
24     }
25     printf("i'm pthread_2!\n");
26     pthread_exit("heiheihei");
27 }
28 
29 
30 
31 int main(int argc, const char *argv[])
32 {
33      
34     char *s1 = "zhangyaqi meimeimei";
35     char *s2 = "jiangtiti meimeimei";
36     //線程調用
37     pthread_create(&tid1,NULL,fun1,s1);
38     pthread_create(&tid2,NULL,fun2,s2);
39 
40     char *ret1 = NULL;
41     char *ret2 = NULL;
42 
43     //阻塞主線程等待全部子線程退出
44     pthread_join(tid1,(void **)&ret1);
45     pthread_join(tid2,(void **)&ret2);
46 
47     printf("pthread1_exit:%s\n",ret1);
48     printf("pthread2_exit:%s\n",ret2);
49 
50 
51     return 0;
52 }
pthread2
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <unistd.h>
 4 
 5 pthread_t tid1,tid2,tid3;
 6 
 7 //線程A
 8 void *fun_a(void *arg)
 9 {
10     while(1)
11     {
12         printf("i'm pthread_a!\n");
13         sleep(1);
14     }
15     pthread_exit(NULL);
16 }
17 //線程B
18 void *fun_b(void *arg)
19 {
20     while(1)
21     {
22         printf("i'm pthread_b!\n");
23         sleep(1);
24     }
25     pthread_exit(NULL);
26 }
27 //線程C
28 void *fun_c(void *arg)
29 {
30     sleep(10);
31     pthread_cancel(tid1);
32     pthread_cancel(tid2);
33 
34     pthread_exit(NULL);
35 }
36 
37 int main(int argc, const char *argv[])
38 {
39     pthread_create(&tid1,NULL,fun_a,NULL);
40     pthread_create(&tid2,NULL,fun_b,NULL);
41     pthread_create(&tid3,NULL,fun_c,NULL);
42 
43     pthread_join(tid1,NULL);
44     pthread_join(tid2,NULL);
45     pthread_join(tid3,NULL);
46 
47 
48 
49     return 0;
50 }
線程取消

 

線程同步和互斥:
同步:自己也是一種特殊的互斥
互斥:

1.全局變量:
作同步沒有問題,互斥時可能會出現問題(最好不要用全局變量作互斥)

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 
 4 pthread_t tida,tidb,tidc;
 5 int leda,ledb,ledc;
 6 
 7 void *pthread_a(void *arg)
 8 {
 9     while(1)
10     {
11         if(leda == 1)
12         {
13             leda--;
14             printf("i'm pthread_a!\n");
15             ledb++;
16         }
17     }
18     pthread_exit(NULL);
19 }
20 
21 void *pthread_b(void *arg)
22 {
23     while(1)
24     {
25         if(ledb == 1)
26         {
27             ledb--;
28             printf("i'm pthread_b!\n");
29             ledc++;
30         }
31     }
32     pthread_exit(NULL);
33 }
34 
35 void *pthread_c(void *arg)
36 {
37     while(1)
38     {
39         if(ledc == 1)
40         {
41             ledc--;
42             printf("i'm pthread_c!\n");
43             leda++;
44         }
45     }
46     pthread_exit(NULL);
47 }
48 
49 
50 
51 int main(int argc, const char *argv[])
52 {
53     //初始化燈
54     leda = 1;
55     ledb = 0;
56     ledc = 0;
57 
58     pthread_create(&tida,NULL,pthread_a,NULL);    
59     pthread_create(&tidb,NULL,pthread_b,NULL);    
60     pthread_create(&tidc,NULL,pthread_c,NULL);    
61 
62     pthread_join(tida,NULL);
63     pthread_join(tidb,NULL);
64     pthread_join(tidc,NULL);
65 
66     return 0;
67 }
全局變量做同步
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 volatile int flag;
 6 
 7 
 8 void *fun_a(void *arg)
 9 {
10     while(1)
11     {
12         if(flag == 1)
13         {
14             flag--;
15             printf("i'm pthread_a!\n");
16             printf("aaaaaaaaaaaaaa\n");
17             flag++;    
18         }
19     }
20     pthread_exit(NULL);
21 }
22 
23 void *fun_b(void *arg)
24 {
25     while(1)
26     {
27         if(flag == 1)
28         {
29             flag--;
30             printf("i'm pthread_b!\n");
31             printf("bbbbbbbbbbbbbb\n");
32             flag++;
33         }
34     }
35     pthread_exit(NULL);
36 }
37 
38 int main(int argc, const char *argv[])
39 {
40     flag = 1;
41     int ret = 0;
42     ret = pthread_create(&tid1,NULL,fun_a,NULL);
43     if(ret != 0)
44     {
45         fprintf(stderr,"fail to create pthread1:%d\n",ret);
46         exit(1);
47     }
48     pthread_create(&tid2,NULL,fun_b,NULL);
49 
50 
51     pthread_join(tid1,NULL);
52     pthread_join(tid2,NULL);
53 
54     return 0;
55 }
全局變量做互斥

 

2.信號量
sem_init 信號量初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
參數:1.sem_init成功執行時獲取對應的信號量編號;  2.決定該信號量用於線程仍是進程 填0表示用於線程;3.信號量的初始值
功能:建立信號量,並設置初始值
返回值:成功返回0,失敗返回-1,並設置errno號

sem_wait p操做
int sem_wait(sem_t *sem);
參數:1.信號量地址
功能:對指定信號量執行-1操做,若是信號量值爲0,則阻塞等待信號量值>0
返回值:成功返回0,失敗返回-1,並設置errno號

sem_post v操做
int sem_post(sem_t *sem);
參數:1.信號量地址
功能:對指定信號量進行+1操做
返回值:成功返回0,失敗返回-1,並設置errno號

sem_destroy
int sem_destroy(sem_t *sem);
參數:1.信號量的地址
功能:銷燬指定信號量
返回值:成功返回0,失敗返回-1,並設置errno號

 1 #include <stdio.h>
 2 #include <semaphore.h>
 3 #include <pthread.h>
 4 
 5 sem_t sem1,sem2,sem3;
 6 pthread_t tid1,tid2,tid3;
 7 
 8 void *pthread_a(void *arg)
 9 {
10     while(1)
11     {
12         sem_wait(&sem1);
13         printf("i'm pthread_a!\n");
14         sem_post(&sem2);
15     }
16     pthread_exit(NULL);
17 }
18 
19 void *pthread_b(void *arg)
20 {
21     while(1)
22     {
23         sem_wait(&sem2);
24         printf("i'm pthread_b!\n");
25         sem_post(&sem3);
26     }
27     pthread_exit(NULL);
28 }
29 
30 void *pthread_c(void *arg)
31 {
32     while(1)
33     {
34         sem_wait(&sem3);
35         printf("i'm pthread_c!\n");
36         sem_post(&sem1);
37     }
38     pthread_exit(NULL);
39 }
40 
41 int main(int argc, const char *argv[])
42 {
43     //初始化
44     sem_init(&sem1,0,1);
45     sem_init(&sem2,0,0);
46     sem_init(&sem3,0,0);
47 
48     //調用線程
49     pthread_create(&tid1,NULL,pthread_a,NULL);
50     pthread_create(&tid2,NULL,pthread_b,NULL);
51     pthread_create(&tid3,NULL,pthread_c,NULL);
52 
53 
54 
55     //線程阻塞
56     pthread_join(tid1,NULL);
57     pthread_join(tid2,NULL);
58     pthread_join(tid3,NULL);
59 
60 
61     //銷燬信號量
62     sem_destroy(&sem1);
63     sem_destroy(&sem2);
64     sem_destroy(&sem3);
65     return 0;
66 }
信號量做同步
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <semaphore.h>
 4 
 5 pthread_t tid1,tid2,tid3;
 6 sem_t sem1; 
 7 
 8 
 9 void *pthread_a(void *arg)
10 {
11     while(1)
12     {
13         sem_wait(&sem1);//阻塞等待  若是sem>0 則-1
14         printf("i'm pthread_a!\n");
15         sem_post(&sem1);//sem +1
16     }
17     pthread_exit(NULL);
18 }
19 
20 
21 void *pthread_b(void *arg)
22 {
23     while(1)
24     {
25         sem_wait(&sem1);
26         printf("i'm pthread_b!\n");
27         sem_post(&sem1);
28     }
29     pthread_exit(NULL);
30 }
31 
32 
33 void *pthread_c(void *arg)
34 {
35     while(1)
36     {
37         sem_wait(&sem1);
38         printf("i'm pthread_c!\n");
39         sem_post(&sem1);
40     }
41     pthread_exit(NULL);
42 }
43 
44 
45 int main(int argc, const char *argv[])
46 {
47     
48     //建立並初始化信號量
49     sem_init(&sem1,0,1);    
50 
51     pthread_create(&tid1,NULL,pthread_a,NULL);
52     pthread_create(&tid2,NULL,pthread_b,NULL);
53     pthread_create(&tid3,NULL,pthread_c,NULL);
54 
55 
56     pthread_join(tid1,NULL);
57     pthread_join(tid2,NULL);
58     pthread_join(tid3,NULL);
59 
60     //銷燬信號量
61     sem_destroy(&sem1);
62 
63 
64     return 0;
65 }
信號量做互斥

 

3.互斥鎖 實現代碼塊之間的互斥
pthread_mutex_init 建立鎖
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
參數:1.當pthread_mutex_init成功執行後獲取鎖號 2.鎖的屬性 填NULL,按默認屬性
返回值:成功返回0,失敗返回錯誤號

pthread_mutex_lock 上鎖
int pthread_mutex_lock(pthread_mutex_t *mutex);
參數:1.鎖號的地址
返回值:成功返回0,失敗返回錯誤號

pthread_mutex_unlock 解鎖
int pthread_mutex_unlock(pthread_mutex_t *mutex);
參數:1.鎖號的地址
返回值:成功返回0,失敗返回錯誤號

pthread_mutex_destroy 銷燬鎖
int pthread_mutex_destroy(pthread_mutex_t *mutex);
參數:1.鎖號的地址
返回值:成功返回0,失敗返回錯誤號

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <stdlib.h>
 4 pthread_t tid1,tid2;
 5 int i = 0;
 6 int a,b;
 7 pthread_mutex_t lock;
 8 
 9 void *fun_a(void *arg)
10 {
11     while(1)
12     {
13         //上鎖
14         pthread_mutex_lock(&lock);
15         i++;
16         a = i;
17         b = a;
18         //解鎖
19         pthread_mutex_unlock(&lock);
20     }
21     pthread_exit(NULL);
22 }
23 
24 void *fun_b(void *arg)
25 {
26     while(1)
27     {
28         pthread_mutex_lock(&lock);
29         if(a != b)
30         {
31             printf("i:%d a:%d b:%d\n",i,a,b);
32         }
33         pthread_mutex_unlock(&lock);
34     }
35     pthread_exit(NULL);
36 }
37 
38 int main(int argc, const char *argv[])
39 {
40     //建立鎖
41     pthread_mutex_init(&lock,NULL);
42 
43     int ret = 0;
44     ret = pthread_create(&tid1,NULL,fun_a,NULL);
45     if(ret != 0)
46     {
47         fprintf(stderr,"fail to create pthread1:%d\n",ret);
48         exit(1);
49     }
50     pthread_create(&tid2,NULL,fun_b,NULL);
51 
52 
53     pthread_join(tid1,NULL);
54     pthread_join(tid2,NULL);
55 
56     //銷燬鎖
57     pthread_mutex_destroy(&lock);
58     return 0;
59 }
互斥鎖

 


4.條件變量
pthread_cond_init 條件變量的初始化
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
參數:1.pthread_cond_init成功執行時獲取條件變量編號 2.條件變量的屬性 填NULL默認屬性
返回值:成功返回0,失敗返回錯誤號

pthread_cond_signal
int pthread_cond_signal(pthread_cond_t *cond);

pthread_cond_broadcast
int pthread_cond_broadcast(pthread_cond_t *cond);

pthread_cond_wait 解鎖->等待->上鎖
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
參數:1.條件變量編號 2.鎖號
返回值:成功返回0,失敗返回錯誤號

pthread_cond_destroy 銷燬信號量
int pthread_cond_destroy(pthread_cond_t *cond);
參數:1.條件變量編號的地址
返回值:成功返回0,失敗返回錯誤號

 1 #include <stdio.h>
 2 #include <pthread.h>
 3 #include <strings.h>
 4 #include <stdlib.h>
 5 
 6 pthread_mutex_t lock;
 7 
 8 pthread_cond_t cond;
 9 
10 pthread_t tid1,tid2,tid3;
11 
12 char buf[128];
13 
14 //線程A  
15 void *fun_a(void *arg)
16 {
17     while(1)
18     {
19         bzero(buf,sizeof(buf));
20         printf("(pthread_a)please input something:\n");
21         fgets(buf,sizeof(buf),stdin);    
22         //pthread_cond_signal(&cond);
23         pthread_cond_broadcast(&cond);
24         sleep(1);
25     }
26     pthread_exit(NULL);
27 }
28 
29 //線程B
30 void *fun_b(void *arg)
31 {
32     while(1)
33     {
34         pthread_mutex_lock(&lock);
35 //        printf("i'm pthread_b!\n");
36 
37         pthread_cond_wait(&cond,&lock);
38         printf("pthread_b buf:%s\n",buf);
39         if(strncmp(buf,"quit",4) == 0)
40         {
41             exit(0);
42         }
43 
44         pthread_mutex_unlock(&lock);
45     }
46     pthread_exit(NULL);
47 }
48 
49 
50 //線程C
51 void *fun_c(void *arg)
52 {
53     while(1)
54     {
55         pthread_mutex_lock(&lock);
56 //        printf("i'm pthread_c!\n");
57 
58         pthread_cond_wait(&cond,&lock);
59         printf("pthread_c buf:%s\n",buf);
60         if(strncmp(buf,"quit",4) == 0)
61         {
62             exit(0);
63         }
64 
65         pthread_mutex_unlock(&lock);
66     }
67     pthread_exit(NULL);
68 }
69 
70 int main(int argc, const char *argv[])
71 {
72     //建立鎖
73     pthread_mutex_init(&lock,NULL);
74     
75     //建立條件變量
76     pthread_cond_init(&cond,NULL);
77 
78     //線程調用
79     pthread_create(&tid1,NULL,fun_a,NULL);
80     pthread_create(&tid2,NULL,fun_b,NULL);
81     pthread_create(&tid3,NULL,fun_c,NULL);
82 
83     //線程阻塞
84     pthread_join(tid1,NULL);
85     pthread_join(tid2,NULL);
86     pthread_join(tid3,NULL);
87 
88     //回收鎖
89     pthread_mutex_destroy(&lock);
90 
91     //回收條件變量
92     pthread_cond_destroy(&cond);
93 
94     return 0;
95 }
條件變量
相關文章
相關標籤/搜索