pthread庫進行多線程程式設計
pthread庫的函數:
1、pthread_create(),建立線程
原型int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void),void *restrict arg);
傳回值:0代表建立成功,否則是錯誤号
使用方法:
聲明pthread_t tid,用來标示線程id;
pthread_create(&tids,NULL,SayHello,NULL);
第一個參數是辨別線程Id,第二個參數是線程屬性,無特殊需要NULL即可,第三個參數是開啟線程的函數,需要聲明為void* Fun(void* args),第四個參數是傳入函數的參數,需要強制類型轉換為void*,且可以用結構體傳入多個參數
2、pthread_join(),等待線程結束
原型:int pthread_join( pthread_t thread, void **value_ptr);
傳回值:0代表成功,否則錯誤号
使用方法:
pthread_join将會阻塞,直到相應id的線程傳回,回收資源;第二個參數用來接收pthread_exit()存放的傳回值;如果主程序退出了,直接傳回。
3、pthread_exit(),退出目前線程
原型:void pthread_exit(void* retval)
使用方法:
調用退出目前線程,類似程序中exit()退出程序,可以傳遞一個指針,join二級指針接收這個指針
4、pthread_attr_init(),初始化線程屬性變量
原型:int pthread_attr_init(pthread_attr_t*attr);
傳回值:0成功
使用方法:
聲明pthread_attr_t attr,用attr變量來辨別線程屬性;
pthread_attr_init(&attr),初始化attr變量,然後可以傳給pthread_create()的第二個參數
5、pthread_mutex_init();pthread_mutex_lock(),pthread_mutex_unlock()互斥鎖的初始化與鎖的使用
原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
init函數是以動态方式建立互斥鎖的,參數attr指定了建立互斥鎖的屬性。如果參數attr為NULL,則使用預設的互斥鎖屬性,預設屬性為快速互斥鎖 。
lock,unlock參數就是初始化生成的鎖,不同線程通路共享變量的時候用lock與unlock,其他線程調用lock就會阻塞,就可以安全的在lock與unlock間通路資源了。
//pthread庫練習
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//#include <pthread.h>
using namespace std;
int num=0;
pthread_mutex_t mutex;
void* SayHello(void* args){
while(1){
pthread_mutex_lock(&mutex);
num++;
cout<<"hello,num="<<num<<" here is "<<*((int*)args)<<endl;
sleep(*(int*)args);
pthread_mutex_unlock(&mutex);
sleep(*(int*)args);
};
pthread_exit(NULL);
}
void* SayWorld(void* args){
pthread_mutex_lock(&mutex);
num++;
cout<<"world,num="<<num<<endl;
int* out=new int;
*out = num;
pthread_mutex_unlock(&mutex);
sleep(50);
pthread_exit((void*)out);
}
int main(){
pthread_mutex_init(&mutex,NULL);
pthread_t tids[5];
int ret;
int *out;
int a[5]={0,1,2,3,4};
pthread_create(&tids[0],NULL,SayWorld,NULL);
for(int i=1;i<5;i++){
ret = pthread_create(&tids[i],NULL,SayHello,(void*)&a[i]);
if(0!=ret) cout<<"pthread created failed"<<endl;
}
cout<<"waiting for World"<<endl;
pthread_join(tids[0],(void**)&out);
cout<<"waiting ok"<<endl;
cout<<"out="<<*out<<endl;
delete out;
return 0;
}
運作結果
world,num=1
hello,num=2 here is 1
waiting for World
hello,num=3 here is 2
hello,num=4 here is 3
hello,num=5 here is 4
hello,num=6 here is 1
hello,num=7 here is 2
hello,num=8 here is 3
hello,num=9 here is 1
hello,num=10 here is 4
hello,num=11 here is 2
hello,num=12 here is 1
hello,num=13 here is 3
hello,num=14 here is 4
hello,num=15 here is 2
hello,num=16 here is 1
hello,num=17 here is 3
hello,num=18 here is 4
hello,num=19 here is 2
hello,num=20 here is 1
hello,num=21 here is 3
hello,num=22 here is 4
waiting ok
out=1
以上實作了thread的幾個函數的應用。pthread_create建立線程,傳進去參數a[i],World函數建立完以後建立其餘Hello,Hello們用互斥鎖的方式實作對共享資源的使用,主程序阻塞在join處等待World的傳回,并且用exit與join接收了World的傳回值。
出的小問題是一開始傳進去的參數是&i,是以一直輸出here is 5,因為i在外面變成5。