程序实验211多线程编程实验报告.docx
《程序实验211多线程编程实验报告.docx》由会员分享,可在线阅读,更多相关《程序实验211多线程编程实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
程序实验211多线程编程实验报告
程序实验二:
11-多线程编程实验
专业班级实验日期5.21姓名学号
实验一(p284:
11-thread.c)
1、软件功能描述
创建3个线程,让3个线程重用同一个执行函数,每个线程都有5次循环,可以看成5个小任务,每次循环之间会有随即等待时间(1-10s)
意义在于模拟每个任务到达的时间是随机的没有任何的特定规律。
2、程序流程设计
3.部分程序代码注释(关键函数或代码)
#include
#include
#include
#defineT_NUMBER3
#defineP_NUMBER5
#defineTIME10.0
void*thrd_func(void*arg)
{
intthrd_num=(int)arg;
intdelay_time=0;
intcount=0;
printf("Thread%disstaraing\n",thrd_num);
for(count=0;count{
delay_time=(int)(rand()*TIME/(RAND_MAX))+1;
sleep(delay_time);
printf("\tTH%d:
job%ddelay=%d\n",thrd_num,count,delay_time);
}
printf("%dfinished\n",thrd_num);
pthread_exit(NULL);
}
intmain()
{
pthread_tthread[T_NUMBER];
intno=0,res;
void*thrd_ret;
srand(time(NULL));
for(no=0;no{
res=pthread_create(&thread[no],NULL,thrd_func,(void*)no);
if(res!
=0)
{
printf("Creayth%dfaild\n",no);
exit(res);
}
}
printf("success\nwaiting\n");
for(no=0;no{
res=pthread_join(thread[no],&thrd_ret);
if(!
res)
{
printf("t%djoined\n",no);
}
else
{
printf("T%djoinedfaild\n",no);
}
}
return0;
}
4.编译、运行方法及结果(抓屏)
5.结果分析
由运行结果可以看出,创建线程、释放资源按照顺序,而每个线程的运行和结束是独立与并行的。
实验二(p287:
11-thread_mutex.c)
1、软件功能描述
在试验1的基础上通过互斥锁,使原本独立,无序的多个线程能够按顺序进行
2、程序流程设计
3.部分程序代码注释(关键函数或代码)
#include
#include
#include
#defineTHREAD_NUMBER3/*线程数*/
#defineREPEAT_NUMBER3/*每个线程的小任务数*/
#defineDELAY_TIME_LEVELS10.0/*小任务间的最大时间间隔*/
pthread_mutex_tmutex;
void*thrd_func(void*arg)//线程函数例程
{
intthrd_num=(int)arg;
intdelay_time=0,count=0;
intres;
//互斥锁上锁
res=pthread_mutex_lock(&mutex);
if(res)
{
printf("Thread%disstarting\n",thrd_num);
pthread_exit(NULL);
}
printf("Thread%disstarting\n",thrd_num);
for(count=0;count{
delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1;
sleep(delay_time);
printf("\tThread%d:
job%ddelay=%d\n",thrd_num,count,delay_time);
}
printf("Thread%dfinished\n",thrd_num);
pthread_exit(NULL);
}
intmain(void)
{
pthread_tthread[THREAD_NUMBER];
intno=0,res;
void*thrd_ret;
srand(time(NULL));
pthread_mutex_init(&mutex,NULL);
for(no=0;no{
res=pthread_create(&thread[no],NULL,thrd_func,(void*)no);
if(res!
=0)
{
printf("Createthread%dfailed\n",no);
exit(res);
}
}
printf("Createthreadssuccess\nWaitingforthreadstofinish...\n");
/*这里的问题很奇怪,按照书上程序敲打,出现的线程首先是2而非0,没有按照书上所说:
与创建顺序相同,但是在这里体现了互斥性,由于后面的释放资源程序从0开始,而一开始为线程2占用资源,所以无法释放资源,导致程序卡死,最后修改为先释放线程2的资源,之后则可以依次显示*/
for(no=2;no{
res=pthread_join(thread[no],&thrd_ret);
if(!
res)
{
printf("Thread%djoined\n",no);
}
else
{
printf("Thread%djoinfailed\n",no);
}
pthread_mutex_unlock(&mutex);
}
pthread_mutex_destroy(&mutex);
return0;
}
4.编译、运行方法及结果(抓屏)
5.结果分析
实验结果体现了互斥性,3个线程有序运行。
实验三(P291:
11-thread_sem.c)
1、软件功能描述
该程序在实验1的基础上,用信号量同步机制实现3个线程的有序执行,利用pv操作来控制执行顺序,达到执行的顺序和创建的顺序刚好相反。
2、程序流程设计
3.部分程序代码注释(关键函数或代码)
……
#include
#include
#include
#include
#defineTHREAD_NUMBER3
#defineREPEAT_NUMBER3
#defineDELAY_TIME_LEVELS10.0
sem_tsem[THREAD_NUMBER];
void*thrd_func(void*arg)
{
intthrd_num=(int)arg;
intdelay_time=0;
intcount=0;
sem_wait(&sem[thrd_num]);
printf("Thread%disstarting\n",thrd_num);
for(count=0;count{
delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1;
sleep(delay_time);
printf("\tThread%d:
job%ddelay=%d\n",thrd_num,count,delay_time);
}
printf("Thread%dfinished\n",thrd_num);
pthread_exit(NULL);
}
intmain(void)
{
pthread_tthread[THREAD_NUMBER];
intno=0,res;
void*thrd_ret;
srand(time(NULL));
for(no=0;no{
sem_init(&sem[no],0,0);
res=pthread_create(&thread[no],NULL,thrd_func,(void*)no);
if(res!
=0)
{
printf("Createthread%dfailed\n",no);
exit(res);
}
}
printf("Createthreadssuccess\nWaitingforthreadstofinish...\n");
sem_post(&sem[THREAD_NUMBER-1]);
for(no=THREAD_NUMBER-1;no>=0;no--)
{
res=pthread_join(thread[no],&thrd_ret);
if(!
res)
{
printf("Thread%djoined\n",no);
}
else
{
printf("Thread%djoinfailed\n",no);
}
sem_post(&sem[(no+THREAD_NUMBER-1)%THREAD_NUMBER]);
}
for(no=0;no{
sem_destroy(&sem[no]);
}
return0;
}
4.编译、运行方法及结果(抓屏)
5.结果分析
程序运行、结束都是按照顺序进行的,只是顺序和创建的顺序刚好相反。
实验四(p295:
11-thread_attr.c)
1、软件功能描述
创建一个线程,具有绑定和分离属性,主线程通过finish——flag标志变量来获得线程结束的消息,不调用pthread_join函数
2、程序流程设计
3.部分程序代码注释(关键函数或代码)
#include
#include
#include
#defineREPEAT_NUMBER3
#defineDELAY_TIME_LEVELS10.0
intfinish_flag=0;
void*thrd_func(void*arg)
{
intdelay_time=0;
intcount=0;
printf("Thisstarting\n");
for(count=0;count{
delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)+1);
sleep(delay_time);
printf("\tTh:
job%ddelay=%d\n",count,delay_time);
}
printf("Thfinished\n");
finish_flag=1;
pthread_exit(NULL);
}
intmain(void)
{
pthread_tthread;
pthread_attr_tattr;
intno=0,res;
void*thrd_ret;
srand(time(NULL));
res=pthread_attr_init(&attr);
if(res!
=0)
{
printf("Createattributefailed\n");
exit(res);
}
res=pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);
res+=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
if(res!
=0)
{
printf("Settingattributefailed\n");
exit(res);
}
res=pthread_create(&th,&attr,thrd_func,NULL);
if(res!
=0)
{
printf("Createthfailed\n");
exit(res);
}
pthread_attr_destroy(&attr);
printf("Createthsuccess\n");
while(!
finish_flag)
{
printf("Waitingforthtofinish...\n");
sleep
(2);
}
return0;
}
4.编译、运行方法及结果(抓屏)
5.结果分析
由结果可以看出,这个创建的线程具有绑定好而分离属性,而且主线程通过一个finish_glag标志变量赖获得线程结束的消息,但是线程在运行结束之后似乎没有收回系统资源,因为程序运行前和程序运行后使用“free”命令查看内存使用情况,发现使用的内存并不一致。
实验五(p298:
11-producer-customer.c)
1、软件功能描述
信号量的意义,在程序生产中和消费过程中是随机进行的,而且生产者的速度比消费者的速度平均快两倍。
生产者一次生产一个单元产品,消费者一次消费一个单元的产品。
2、程序流程设计
3.部分程序代码注释(关键函数或代码)
#include
#include
#include
#include
#include
#include
#include
#include
#defineMYFIFO"myfifo"
#defineBUFFER_SIZE3
#defineUNIT_SIZE5
#defineRUN_TIME30
#defineDELAY_TIME_LEVELS5.0
intfd;
time_tend_time;
sem_tmutex,full,avail;
void*producer(void*arg)
{
intreal_write;
intdelay_time=0;
while(time(NULL){
delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)/2.0)+1;
sleep(delay_time);
sem_wait(&avail);
sem_wait(&mutex);
printf("\nProducer:
delay=%d\n",delay_time);
if((real_write=write(fd,"hello",UNIT_SIZE))==-1)
{
if(errno==EAGAIN)
{
printf("TheFIFOhasnotbeenreadyet.Pleasetrylatter\n");
}
}
else
{
printf("Write%dtotheFIFO\n",real_write);
}
sem_post(&full);
sem_post(&mutex);
}
pthread_exit(NULL);
}
void*customer(void*arg)
{
unsignedcharread_buffer[UNIT_SIZE];
intreal_read;
intdelay_time;
while(time(NULL){
delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1;
sleep(delay_time);
sem_wait(&full);
sem_wait(&mutex);
memset(read_buffer,0,UNIT_SIZE);
printf("\nCustomer:
delay=%d\n",delay_time);
if((real_read=read(fd,read_buffer,UNIT_SIZE))==-1)
{
if(errno==EAGAIN)
{
printf("Nodatayet\n");
}
}
printf("Read%sfromFIFO\n",read_buffer);
sem_post(&avail);
sem_post(&mutex);
}
pthread_exit(NULL);
}
intmain()
{
pthread_tthrd_prd_id,thrd_cst_id;
pthread_tmon_th_id;
intret;
srand(time(NULL));
end_time=time(NULL)+RUN_TIME;
if((mkfifo(MYFIFO,O_CREAT|O_EXCL)<0)&&(errno!
=EEXIST))
{
printf("Cannotcreatefifo\n");
returnerrno;
}
fd=open(MYFIFO,O_RDWR);
if(fd==-1)
{
printf("Openfifoerror\n");
returnfd;
}
ret=sem_init(&mutex,0,1);
ret+=sem_init(&avail,0,BUFFER_SIZE);
ret+=sem_init(&full,0,0);
if(ret!
=0)
{
printf("Anysemaphoreinitializationfailed\n");
returnret;
}
ret=pthread_create(&thrd_prd_id,NULL,producer,NULL);
if(ret!
=0)
{
printf("Createproducerthreaderror\n");
returnret;
}
ret=pthread_create(&thrd_cst_id,NULL,customer,NULL);
if(ret!
=0)
{
printf("Createcustomerthreaderror\n");
returnret;
}
pthread_join(thrd_prd_id,NULL);
pthread_join(thrd_cst_id,NULL);
close(fd);
unlink(MYFIFO);
return0;
}
4.编译、运行方法及结果(抓屏)
5.结果分析
由实验结果可以看出生产者的速度比消费者的速度平均快2倍左右。