c/c++ Linux多線程編程

Linux多線程編程c++


線程概念編程

線程是指運行中的程序的調度單位。一個線程指的是進程中一個單一順序的控制流,也被稱爲輕量級線程。它是系統獨立調度和分配的基本單位。同一進程中的多個線程將共享該系統中的所有系統資源,好比文件描述符和信號處理等。一個進程能夠有不少線程,每一個線程並行執行不一樣的任務。服務器

線程與進程比較多線程

① 和進程相比,它是一種很是「節儉」的多任務操做方式。在Linux系統中,啓動一個新的進程必須分配給它獨立的地址空間,創建衆多的數據表來維護其代碼段、堆棧段和數據段,這種多任務工做方式的代價很是「昂貴」。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分數據,啓動一個線程所花費的空間遠遠小於啓動一個進程所花費的空間,並且線程間彼此切換所須要時間也遠遠小於進程間切換所須要的時間。架構

② 線程間方便的通訊機制。對不一樣進程來講它們具備獨立的數據空間,要進行數據的傳遞只能經過通訊的方式進行。這種方式不只費時,並且很不方便。線程則否則,因爲同一進程下的線程之間共享數據空間,因此一個線程的數據能夠直接爲其餘線程所用,不只方便,並且快捷。函數

線程基本編程學習

Linux系統下的多線程遵循POSIX線程接口,稱爲pthread。編寫Linux下的多線程程序,須要使用頭文件pthread.h,鏈接時須要使用庫libpthread.a。由於pthread的庫不是Linux系統的庫,因此在編譯時要加上 -lpthread。例如:gcc filename -lpthread。注意,這裏要講的線程相關操做都是用戶空間中的線程的操做。spa

線程建立:建立線程實際上就是肯定調用該線程函數的入口點,這裏一般使用的函數是pthread_create()。在線程建立後,就開始運行相關的線程函數。線程

線程退出:在線程建立後,就開始運行相關的線程函數,在該函數運行完以後,該線程也就退出了,這也是線程退出的一種方法。另外一種退出線程的方法是使用函數pthread_exit(),這是線程的主動行爲。這裏要注意的是,在使用線程函數時,不能隨意使用exit()退出函數來進行出錯處理。因爲exit()的做用是使調用進程終止,而一個進程每每包含多個線程,所以,在使用exit()以後,該進程中的全部線程都終止了。在線程中就可使用pthread_exit()來代替進程中的exit()。3d

線程等待:因爲一個進程中的多個線程是共享數據段的,所以,一般在線程退出後,退出線程所佔用的資源並不會隨着線程的終止而獲得釋放。正如進程之間能夠用wait()系統調用來同步終止並釋放資源同樣,線程之間也有相似機制,那就是pthread_join()函數。pthread_join()用於將當前進程掛起來等待線程的結束。這個函數是一個線程阻塞的函數,調用它的函數將一直等待到被等待的線程結束爲止,當函數返回時,被等待線程的資源就被收回。

線程取消:前面已經提到線程調用pthread_exit()函數主動終止自身線程,可是在不少線程應用中,常常會遇到在別的線程中要終止另外一個線程的問題,此時調用pthread_cancel()函數來實現這種功能,但在被取消的線程的內部須要調用pthread_setcancel()函數和pthread_setcanceltype()函數設置本身的取消狀態。例如,被取消的線程接收到另外一個線程的取消請求以後,是接受函數忽略這個請求;若是是接受,則再判斷馬上採起終止操做仍是等待某個函數的調用等。

線程標識符獲取:獲取調用線程的標識ID。

線程清除:線程終止有兩種狀況:正常終止和非正常終止。線程主動調用pthread_exit()或者從線程函數中return都將使線程正常退出,這是可預見的退出方式;非正常終止是線程在其它線程的干預下,或者因爲自身運行出錯(好比訪問非法地址)而退出,這種退出方式是不可預見的。不管是可預見的線程終止仍是異常終止,都回存在資源釋放的問題,如何保證線程終止時能順利地釋放掉本身所佔用的資源,是一個必須考慮的問題。

從pthread_cleanup_push()的調用點到pthread_cleanup_pop()之間的程序段中的終止動做(包括調用pthread_exit()和異常終止,不包括return)都將執行pthread_cleanup_push()所指定的清理函數。

Linuxc/c++服務器開發高階視頻學習資料+qun720209036獲取


更多視頻內容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒體,P2P,K8S,Docker,TCP/IP,協程,DPDK多個高級知識點分享。

視頻連接:C/C++Linux服務器開發/後臺架構師-學習視頻

一、如何利用2個條件變量實現線程同步?

思路:就是來回的利用pthread_cond_signal()函數,當一方被阻塞時,喚醒函數能夠喚醒pthread_cond_wait()函數,只不過pthread_cond_wait()這個方法要執行其後的語句,必須遇到下一個阻塞(也就是pthread_cond_wait()方法時),才執行喚醒後的其後語句。

代碼以下:

include<stdio.h>

include<unistd.h>

include<stdlib.h>

include<string.h>

include<pthread.h>

define MAX_NUM 2static int count = 1;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t js = PTHREAD_COND_INITIALIZER;pthread_cond_t os = PTHREAD_COND_INITIALIZER;void A(void arg){

pthread_mutex_lock(&mutex);

while(count <= MAX_NUM)

{

if(count%2 == 1){

printf("A = %dn", count);

count++;

pthread_cond_signal(&os);

sleep(5);

printf("bbbbbbbbbbbbbbbbbbbbbbbbbbbn");

}else{

printf("cccccccccccccccccccccccccccn");

pthread_cond_wait(&js, &mutex);

printf("dddddddddddddddddddddddddddn");

}

pthread_mutex_unlock(&mutex);

}}

void B(void arg)

{

pthread_mutex_lock(&mutex);

while(count <= MAX_NUM){

if(count%2 == 0){

printf("B = %dn", count);

count++;

pthread_cond_signal(&js);

}

else

{

pthread_cond_wait(&os, &mutex);

printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaan");

}

}

pthread_mutex_unlock(&mutex);

}

int main(void)

{

pthread_t tid1, tid2;

pthread_create(&tid2, NULL, B, NULL);

sleep(1);

pthread_create(&tid1, NULL, A, NULL);

pthread_join(tid1, NULL);

pthread_join(tid2, NULL);

return 0;

}

運行結果

上面的這個程序就是:2個條件變量對一個互斥量的操做。signal()發送喚醒wait(),wait()以後的語句暫時不執行,直到下一次遇到wait()時,阻塞,返回執行喚醒的wait()以後的語句。

二、怎麼建立10個線程的開始運行和結束過程?

利用2個條件變量和1個互斥量便可實現。

代碼以下:

include<stdio.h>

include<unistd.h>

include<stdlib.h>

include<string.h>

include<pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;void thread_fun1(void arg){

int i = (int )arg;

pthread_mutex_lock(&mutex);

printf("[%d] thread start upn", i);

pthread_cond_wait(&cond, &mutex);

printf("[%d]thread is wake upn", i);

pthread_mutex_unlock(&mutex);

}

void thread_fun2(void arg)

{

pthread_cond_broadcast(&cond); //廣播,一次喚醒全部的線程}int main(void){

pthread_t tid1[10], tid2;

int i;

for(i = 0; i < 10; i++)

{

pthread_create(&tid1[i], NULL, thread_fun1, &i);//建立10個線程

sleep(1);

}

pthread_create(&tid2, NULL, thread_fun2, NULL);//建立1個線程

for(i = 0; i < 10; i++)

{ //主線程等子線程執行完

pthread_join(tid1[i], NULL);

}

pthread_join(tid2, NULL);

return 0;

}

運行結果

多線程的編程中:互斥量、條件變量是重中之重!!!

相關文章
相關標籤/搜索