Linux c多執行緒程式設計的4個例項
在主流的作業系統中,多工一般都提供了程序和執行緒兩種實現方式,程序享有獨立的程序空間,而執行緒相對於程序來說是一種更加輕量級的多工並行,多執行緒之間一般都是共享所在程序的記憶體空間的。
Linux也不例外,雖然從核心的角度來看,執行緒體現為一種對程序的"克隆"(clone),共享程序的資源。但是在使用者空間提供了執行緒管理機制來實現對執行緒的管理,目前Linux中最流行的執行緒機制為LinuxThreads,下面以一個多執行緒程式設計例項來介紹該執行緒庫的程式設計介面:
示例1:執行緒的建立和退出,等待執行緒結束和獲取執行緒的返回值
#include
#include
#include
/************************************************************
*執行緒函式:執行緒執行執行的函式
*引數p:通用型別的指標,啟動執行緒時傳遞給執行緒函式的引數
*返回值:通用型別指標,執行緒結束後啟動執行緒的函式可以獲取該值
*************************************************************/
void* task(void* p){
double r = *(double*)p;
printf("%lf\n",3.14*r*r);
}
void* task2(void* p){
static int sum = 0;
int i;
for(i=1;i<11;i++)
sum = sum+i;
return ∑
//pthread_exit(&sum);執行緒退出,和return等價
}
int main(){
pthread_t id1,id2;
double d = 1.0;
int* pi = NULL;
/*
*建立執行緒函式,在主執行緒中呼叫該函式可以建立執行緒
*引數1:執行緒ID,ID由系統分配,該引數是一個傳出引數,型別為pthread_t *
*引數2:執行緒屬性,使用預設屬性給0即可,型別為pthread_attr_t *
*引數3:執行緒函式,即執行緒執行時程式碼,型別為void *(*)(void *)
*引數4:傳遞給執行緒函式的引數
*/
pthread_create(&id1,0,task,&d);//計算圓的面積
pthread_create(&id2,0,task2,0);//計算累加和
/*
*等待執行緒結束函式,用於在一個執行緒中等待另外一個執行緒結束
*引數1:要等待結束的執行緒的ID
*引數2:結束執行緒的返回值的地址(由於是傳出引數,所以是返回值的地址)
*/
pthread_join(id1,0);
pthread_join(id2,(void**)&pi);//pi=∑
printf("sum=%d\n",*pi);
return 0;
}
此外,我們還可以設定執行緒的屬性,下面介紹設定執行緒分離屬性的程式碼
示例2:設定執行緒的分離屬性
#include
#include
//執行緒函式
void* task(void* p){
int i;
for(i=0;i<50;i++){
printf("%d\n",i);
usleep(100000);//0.1秒
}
}
int main(){
pthread_t id;
pthread_create(&id,0,task,0);
/*
*將執行緒設定為分離屬性,分離屬性的執行緒一旦結束,直接回收資源
*因此當執行緒設定為分離屬性後將無法再等待執行緒結束和獲取執行緒的返回值
*引數:設定分離屬性的執行緒ID
*/
pthread_detach(id);//detach的執行緒join
//pthread_join(id,0);//無效
int i;
for(i=0;i<50;i++){
printf("main:%d\n",i);
usleep(100000);//0.1秒
}
}
由於多執行緒之間是共享程序資源的,所以多執行緒程式設計時需要對共享資源的訪問進行保護
包括互斥和同步,常用的方式包括互斥鎖和訊號量
示例3:互斥鎖的使用
#include
#include
char* data[5];//定義一個長度是5字串陣列
int size = 0;//定義了當前下標,也是人數
pthread_mutex_t lock;//1 宣告
void* task(void* p){
pthread_mutex_lock(&lock);//3 加鎖
data[size] = (char*)p; //4 訪問共享資源
usleep(10000); ++size;
pthread_mutex_unlock(&lock);//5 解鎖
}
int main(){
data[size] = "liubei"; size++;
pthread_mutex_init(&lock,0);//2 初始化
pthread_t id1,id2;
pthread_create(&id1,0,task,"zhangfei");
pthread_create(&id2,0,task,"guanyu");
pthread_join(id1,0);
pthread_join(id2,0);
pthread_mutex_destroy(&lock);//6 刪除
int i;
for(i=0;i
printf("%s\n",data);
}
示例4:訊號量的使用
#include
#include
#include
#include
sem_t sem; //1 分配
void* task(void* p){
int i = (int)p;
printf("第%d個執行緒申請連線\n",i);
sem_wait(&sem);//3 P操作(計數-1)
printf("第%d個執行緒申請成功\n",i);
srand(time(0));//4 模擬訪問共享資源
sleep(rand()%10);
printf("第%d個執行緒釋放資源\n",i);
sem_post(&sem);//5 V操作(計數+1)
}
int main(){
sem_init(&sem,0,10);//2 初始化
int i;
for(i=1;i<16;i++){
pthread_t id;
pthread_create(&id,0,task,(void*)i);
}
while(1);
}
linux學習交流群:690327559
linux免費學習課程 :
linux基礎
http://www.makeru.com.cn/course/details/2058?s=26056
C高階之linux
http://www.makeru.com.cn/course/details/2478?s=26056
linux多執行緒程式設計
http://www.makeru.com.cn/course/details/1937?s=26056