在主流的操作系统中,多任务一般都提供了进程和线程两种实现方式,进程享有独立
的进程空间,而线程相对于进程来说是一种更加轻量级的多任务并行,多线程之间一般都是共
享所在进程的内存空间的。
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[i]);
}
示例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);
}