Linux提供了线程库pthread.h,本实验涉及的库函数有pthread_create()和pthread_ join()等。
■pthread_create()函数
功能:创建一个ULT。
原型:
intpthread_create(pthread_t*tid,pthread_attr_t*attr,
void *(*fun)(void), void *arg);
其中,
第一个参数tid是指向线程标识符的指针;
第二个参数attr是需要设置的特殊属性,一般不需要什么特殊属性,可赋值NULL;
第三个参数是线程将要启动执行的函数指针,即函数名;
第四个参数是要传递给该线程的参数的指针。
函数的返回值为0,表示创建成功,否则表示创建失败。
■pthread__exit()函数
功能:线程自行终止。
原型:voidpthread_exit(intstatus);
参数status为0表示正常终止,非0表示异常终止。
■pthread_ join()函数
功能:进程等待线程终止(作用相当于进程控制中的wait函数)
原型:
intpthread_ join(pthread_tthread,void_**status);
其中,参数thread指定要等待的线程;参数status指向线程的返回值。
该函数返回0表示成功,即指定的线程已正常终止;非0表示失败,即线程执行发生错误。
1、创建线程
用gcc编译:
由于头文件pthread.h实际上不是Linux默认的库,故在gcc命令行中需要使用选项“-l”链接该库,如:
gcc–otest4_1 –lpthreadtest4_1.c
2、多线程间共享数据
设计一个售票模拟系统进程,在其main函数中创建2个售票终端线程,这2个线程共享进程的全局数据——余票数据库ticket和余票数rest。下面给出部分程序,请设计出其余部分,并完成编辑、编译及调试运行。
/*test_2.c :售票模拟系统*/
代码:
#include
#include
#include
pthread_mutex_t stage[2]; //设定1个互斥信号量2个平台
int ticket[10]={1,3,5,7,9,2,4,6,8,10};
int rest=10;
void *terminal(int *num)
{
int tn=*num;
int tot=0;
long i;
while(1)
if(rest>0)
{
pthread_mutex_lock(&stage[tn]); //互斥信号量的P操作
rest--;
printf("Terminal_%d:sell a ticket,num=%d\n",tn,ticket[rest]);
tot++;
pthread_mutex_unlock(&stage[tn]); //互斥信号量的V操作
for(i=0;i<999999;i++);
}
else
{
pthread_mutex_lock(&stage[tn]); //互斥信号量的P操作
printf("Selled %d tickets from terminal_%d\n",tot,tn);
pthread_mutex_unlock(&stage[tn]); //互斥信号量的V操作
break;
}
pthread_exit(0);
}
int main()
{
pthread_t tid[2]; //由于有2个终端,所以必须有两个线程
int num[2]={1,2};
int i,r;
for(i=0;i<2;i++)
{
pthread_mutex_init(&stage[i],NULL); //初始化两个互斥信号量
}
for(i=0;i<2;i++)
{
int *n=&num[rand()%2];
r=pthread_create(&tid[i],NULL,(void *)(* terminal),n);
if(r!=0)
{
printf("create of terminal_%d is fail\n",n);
exit(-1);
}
}
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
for(i=0;i<2;i++) //清理两个互斥信号量
{
pthread_mutex_destroy(&stage[i]);
}
printf("Over!\n");
return 0;
}
实验截图