天天看點

linux基礎——線程

線程基礎

線程的建立、退出、分離、彙合

建立線程使用pthread_create

代碼示例

線程的退出

線程的彙合和分離

線程對共享資源(臨界資源)的通路

線程同步

線程同步——mutex鎖

線程同步——條件變量

線程同步——信号量

程序間通訊(IPC)信号量集

程序和程式

程序是資源配置設定的基本機關,而線程是執行的基本機關。

程序和線程的關系

一個程序中可以有多個線程,最少有一個線程(主線程)。線程共享程序的資源。每個線程有自己獨有的屬性,線程id(tid)、線程棧幀、線程自己的信号屏蔽字等。程序的切換和程序間的通訊,消耗資源非常大且效率低下。而線程共享程序的資源,線程的切換和線程間的通訊很靈活、消耗資源非常少、效率很高。

驗證一個程序中有多個線程,需要擷取到程序的pid和線程的tid,擷取程序的pid使用getpid函數即可,而擷取線程的tid則使用pthread_self函數

pthread_c.c

執行結果

linux基礎——線程

return和exit的差別:

線上程函數中調用return隻是線程執行函數的結束。代表了線程的結束。如果線上程函數中調用exit函數将會終止整個程序,那麼程序中的所有線程都會終止。是以切記,一定不要線上程執行函數中調用exit等函數。

終止一個線程使用pthread_exit函數。

調用pthread_cancel函數将終止其它線程

線程建立後,線程退出的時候,線程的資源自動回收,不需要主線程等待,這樣的線程稱為分離線程。

線程的分離使用pthread_detach函數

線程建立以後,線程退出後需要其它線程來回收該線程的資源,這樣的線程稱為線程的彙合。

線程彙合使用pthread_join()函數。

pthread_e.c

linux基礎——線程

線程建立完畢,程序中的所有線程都是異步的。

要保證線程函數的安全,那麼線程函數必須是可重入的。如果線程函數是不可重入的,那麼對臨界資源的通路将造成程式的亂序。

pthread_t.c

linux基礎——線程

多個線程對臨界資源進行通路的時候,需要由異步變為同步。

POSIX線程中提供了三種方式來進行線程同步。

mutex鎖

條件變量

信号量

pthread_mutex_init

pthread_mutex_lock

pthread_mutex_trylock

pthread_mutex_unlock

pthread_mutex_destroy

pthread_m.c

linux基礎——線程

什麼是條件變量?

線程間的同步有這樣一種情況:線程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

linux基礎——線程

對于多個資源的共享使用信号量。

想使用其中的一個資源的時候,首先判斷是否有可用資源。如果有,是資源的可用數量減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

linux基礎——線程

信号量集就是有一個或多個信号量組成的集合。

如何使用信号量集實作程序間的通訊?

擷取一個鍵值。

通過鍵值擷取信号量集semid。

semget(2)

對信号量集中的某一個信号量進行pv操作

使用函數semop(2)

為信号量集中的某一個信号量設定初值。或者擷取信号量的值。

控制信号量集中某一個信号量,需要使用到semctl(2)

使用程序間通訊模仿TCP通訊結果。

server.c

client.c