線程基礎
線程的建立、退出、分離、彙合
建立線程使用pthread_create
代碼示例
線程的退出
線程的彙合和分離
線程對共享資源(臨界資源)的通路
線程同步
線程同步——mutex鎖
線程同步——條件變量
線程同步——信号量
程序間通訊(IPC)信号量集
程序和程式
程序是資源配置設定的基本機關,而線程是執行的基本機關。
程序和線程的關系
一個程序中可以有多個線程,最少有一個線程(主線程)。線程共享程序的資源。每個線程有自己獨有的屬性,線程id(tid)、線程棧幀、線程自己的信号屏蔽字等。程序的切換和程序間的通訊,消耗資源非常大且效率低下。而線程共享程序的資源,線程的切換和線程間的通訊很靈活、消耗資源非常少、效率很高。
驗證一個程序中有多個線程,需要擷取到程序的pid和線程的tid,擷取程序的pid使用getpid函數即可,而擷取線程的tid則使用pthread_self函數
pthread_c.c
執行結果

return和exit的差別:
線上程函數中調用return隻是線程執行函數的結束。代表了線程的結束。如果線上程函數中調用exit函數将會終止整個程序,那麼程序中的所有線程都會終止。是以切記,一定不要線上程執行函數中調用exit等函數。
終止一個線程使用pthread_exit函數。
調用pthread_cancel函數将終止其它線程
線程建立後,線程退出的時候,線程的資源自動回收,不需要主線程等待,這樣的線程稱為分離線程。
線程的分離使用pthread_detach函數
線程建立以後,線程退出後需要其它線程來回收該線程的資源,這樣的線程稱為線程的彙合。
線程彙合使用pthread_join()函數。
pthread_e.c
線程建立完畢,程序中的所有線程都是異步的。
要保證線程函數的安全,那麼線程函數必須是可重入的。如果線程函數是不可重入的,那麼對臨界資源的通路将造成程式的亂序。
pthread_t.c
多個線程對臨界資源進行通路的時候,需要由異步變為同步。
POSIX線程中提供了三種方式來進行線程同步。
mutex鎖
條件變量
信号量
pthread_mutex_init
pthread_mutex_lock
pthread_mutex_trylock
pthread_mutex_unlock
pthread_mutex_destroy
pthread_m.c
什麼是條件變量?
線程間的同步有這樣一種情況:線程A需要等待某個條件成立才會繼續往下執行,如果條件不成立則阻塞等待,而線程B在執行過程中使得這個條件成立,然後喚醒線程A繼續往下執行。那麼這個條件就是條件變量。
pthread庫中通過使用pthread_cond_t類型來表示條件變量類型。
對這種類型的操作包括以下:
pthread_cond_init(3)
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);
使用條件變量完成一個生産者和消費者的問題。
p_c.c
對于多個資源的共享使用信号量。
想使用其中的一個資源的時候,首先判斷是否有可用資源。如果有,是資源的可用數量減1.如果沒有可用資源,線程等待其他線程釋放資源。當線程釋放資源的時候,資源可用數量加1.
信号量是一個類型 sem_t
關于信号量的操作,系統提供了以下函數
sem_init(3)
sem_destroy(3)
sem_post(3)
sem_wait(3)
int sem_trywait(sem_t *sem);
使用信号量完成生産者和消費者模型,不再使用連結清單,使用循環隊列完成。
p_cq.c
信号量集就是有一個或多個信号量組成的集合。
如何使用信号量集實作程序間的通訊?
擷取一個鍵值。
通過鍵值擷取信号量集semid。
semget(2)
對信号量集中的某一個信号量進行pv操作
使用函數semop(2)
為信号量集中的某一個信号量設定初值。或者擷取信号量的值。
控制信号量集中某一個信号量,需要使用到semctl(2)
使用程序間通訊模仿TCP通訊結果。
server.c
client.c