linux 多執行緒

NO IMAGE

1,執行緒與程序的區別
(1)程序
是一個正在執行的程式,是系統資源分配的實體
每個程序都有自己的PCB
(2)執行緒
程序和執行緒建立 核心使用的都是clone函式;
所有的預設的執行緒平分棧的大小
執行緒棧與執行緒棧之間有一款執行緒安全區。
程序是資源競爭的基本單位
執行緒是程式執行的最小單位
執行緒共享程序資料,程式碼段,堆,但是有自己擁有的東西:執行緒ID>一組暫存器>棧>errno>訊號遮蔽字>排程優先順序
執行緒中最好不要處理訊號;

作業系統引入執行緒的目的:
程序在執行時,由於程序排程演算法的原因,不可避免的會出現程序之間的切換,而程序之間的切換時非常耗時的,為了解決這一問題,引入了多執行緒的解決方法;
執行緒,又稱輕程序,在一個程序中建立多個執行緒去處理多個問題,執行緒在切換時不會切換程序,從而節省了時間。
不同程序的執行緒之間切換會引起程序的切換,同一程序中的執行緒切換不會引起程序的切換。程序的切換一定會引起執行緒的切換。

2,執行緒操作
(1)執行緒的建立
int pthread_create(pthread_t thread, const pthread_attr_t *attr, void (start_routine) (void ), void *arg);
pthread_create(執行緒ID,執行緒屬性,執行緒需要執行的函式的地址,傳給執行緒啟動函式的引數)
(2)等待執行緒
int pthread_join(pthread_t thread,void **arg);
(3)結束執行緒
1,return
2,pthread_exit;(只會退出一個執行緒,不能退出程序,程序中的其他執行緒依然在執行,最後一個執行緒例外)
3,pthread_cancel;(關閉一個其他的執行緒)//遇到一個cancel點才會結束到一個執行緒
pthread_testcancel();(設定cancel點)
(4)獲取執行緒id
pthread_t pthread_self();
(5)執行緒分離
int pthread_detach(pthread_t tid);
(6)初始化執行緒
int pthread_attr_init(pthread_attr_t* attr);

int ptnread_attr_destory(pthread_attr_t* attr);
Detach state        = PTHREAD_CREATE_JOINABLE  //執行緒分離屬性
Scope               = PTHREAD_SCOPE_SYSTEM
Inherit scheduler   = PTHREAD_INHERIT_SCHED
Scheduling policy   = SCHED_OTHER   
Scheduling priority = 0
Guard size          = 4096 bytes  //執行緒之間的安全距離
Stack address       = 0x40196000  //執行緒棧初始地址
Stack size          = 0x201000 bytes  //執行緒棧大小
(1)自己定義執行緒棧
int pthread_attr_setstack(pthread_attr_ t* attr, void* attraddr,size_t stacksize);
(2)設定執行緒棧的大小
int pthread_attr_setstacksize(pthread_attr_t * attr,size_t stacksize);

下面建立一個執行緒例項來加深理解

#include <stdio.h>                                                                                    #include <stdlib.h>
#include <pthread.h>
#include <string.h>
void *route1()
{
while(1)
printf("hello\n");
}
void *route2()
{
while(1)
printf("hello router2\n");
}
void *route3()
{
while(1)
printf("hello route3\n");
}
int main() {
pthread_t tid1;
pthread_t tid2;
pthread_t tid3;
int ret1 =  pthread_create(&tid1,NULL,route1,NULL);
if(ret1!=0)
printf("pthread_create:%s\n",strerror(ret1));
int ret2 = pthread_create(&tid2,NULL,route2,NULL);
if(ret2!=0)
printf("ptreath_create2:%s\n",strerror(ret2));
int ret3 = pthread_create(&tid3,NULL,route3,NULL);
if(ret3!=0)
printf("pthread_create3:%s\n",strerror(ret3));
//1當程序退出,程序中所有執行緒就退出
//解決辦法:pthread_join等待執行緒
//2建立好執行緒以後,每個執行緒都從參與時間片的分配
//3當執行緒處理函式結束之後,執行緒就結束
// pthread_join(tid,NULL);
while(1)
printf("hello.man\n");
}

執行緒的同步與互斥
1,執行緒分離
pthread_detach(pthread_t thread);

//互斥鎖:同步執行緒對共享資料的訪問
建議鎖,不是強制的
1,定義全域性變數  pthread_mutex_t metux; 
2,初始化  pthread_mutex_init(&metux,NULL);
3, 上鎖:pthread_mutex_lock(&mutex);                      mutex ==1 將mutex置0?返回
mutex==0? 等待
4,解鎖:pthread_mutex_unlock(&mutex);         mutex=1,返回
5,銷燬:pthread_mutex_destory(&mutex);
void pthread_cleanup_push(void(*routine)(void*),void *arg);  回撥函式遇到//1pthread_exit()        才會觸發
//2,pthread_cancel()
//3,pop(1)
void pthread_cleanup_pop(int execute);

//自旋鎖
1,pthread_spin_t spin
2,pthrad_t_spin_init
3,pthrad_t_spin_lock
4,pthrad_t_spin_unlock
5,pthrad_t_spin_destory

//讀寫鎖:讀讀共享,讀寫互斥,寫的優先順序高
1,pthread_rwlock_t rwlock;
2,pthread_rwlock_init(&rwlock,NULL)
3,pthread_rwlock_rdlock(&rwlock);
4,pthread_rwlock_wrlock(&rwlock);
5,pthread_rwlock_unlock(&rwlock);
6,pthread_rwlock_destory(&rwlock);
//條件變數   同步共享資料的值
1,pthread_cond_t cond
2,pthread_cond_init(&cond,NULL)
3,pthread_cond_wait(&cond,&mutex)  //阻塞,將mutex置為1
//返回,將mutex恢復為原樣
4,pthread_cond_signal(&cond)
5,pthread_cond_destory(&cond)
使用規範:
pthread_mutex_lock(&mutex);
while(條件不滿足)
pthread_cond_wait(&cond,&mutex)
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex); 
pthread_cond_signal(&cond); //如果沒有執行緒等在wait,singal就丟失
pthread_mutex_unlock(&mutex);

POSIX訊號量:
初始化訊號量
int sem_init(sem_t*sem,
int pshare,//表示本程序內多個執行緒的同步互斥
unsigned int value);//設定初值
銷燬訊號量
int sem_destory(sem_t* sem);

      p操作
int sem_wait(sem_t* sem);
v操作
int sem_post(sem_t* sem);