進程創建,進程的調度較爲消耗硬件資源,進程切換時會涉及到多個硬件資源的切換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 }
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 }
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 }