天天看點

pthread多線程的練習

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。