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。