实验二linux操作系统.docx

上传人:b****9 文档编号:25228868 上传时间:2023-06-06 格式:DOCX 页数:29 大小:538.10KB
下载 相关 举报
实验二linux操作系统.docx_第1页
第1页 / 共29页
实验二linux操作系统.docx_第2页
第2页 / 共29页
实验二linux操作系统.docx_第3页
第3页 / 共29页
实验二linux操作系统.docx_第4页
第4页 / 共29页
实验二linux操作系统.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

实验二linux操作系统.docx

《实验二linux操作系统.docx》由会员分享,可在线阅读,更多相关《实验二linux操作系统.docx(29页珍藏版)》请在冰豆网上搜索。

实验二linux操作系统.docx

实验二linux操作系统

程序实验2:

多线程编程实验

实验周次9实验日期2014/4/20姓名张括学号20112435

实验一(p284:

11-thread.c)

1、软件功能描述

创建线程实际上就是确定调用该线程函数的入口点,通常使用的函数是pthread_create()。

在线程创建以后,就开始运行相关的线程函数,在该函数运行完之后,该线程也就退出,这是线程退出一种方法。

另一种退出线程的方法是使用函数pthread_exit(),这是线程的主动行为。

本实验程序创建了3个线程,这3个线程重用一个函数,每个线程循环5次,随机等待1-10s时间。

2、程序流程设计

 

3.部分程序代码注释(关键函数或代码)

……

/*thread.c*/

#include

#include

#include

#defineTHREAD_NUMBER3

#defineREPEAT_NUMBER5

#defineDELAY_TIME_LEVELS10.0

void*thrd_func(void*arg)

{

intthrd_num=(int)arg;

intdelay_time=0;

intcount=0;

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

{

res=pthread_create(&thread[no],NULL,thrd_func,(void*)no);

if(res!

=0)

{

printf("Createthread%dfailed\n",no);

exit(res);

}

}

printf("Createtreadssuccess\nWaitingforthreadstofinish...\n");

for(no=0;no

{

res=pthread_join(thread[no],&thrd_ret);

if(!

res)

{

printf("Thread%djoined\n",no);

}

else

{

printf("Thread%djoinfailed\n",no);

}

}

return0;

}

……

4.编译、运行方法及结果(抓屏)

5.结果分析

……

通过上述实验,根据运行结果可以看出程序中创建了三个线程,且每个线程中的5个任务循环等待时间是随机的,这样任务到达的时间也是随机的,所以线程2中的任务可能会比线程1的任务线执行,即线程2可能会比线程1先运行结束。

实验二(p287:

11-thread_mutex.c)

1、软件功能描述

由于线程共享进程的资源和地址空间,因此在对这些资源进行操作的时候,必须考虑到线程间资源访问的同步与互斥问题。

本实验主要利用互斥锁机制,保证让每个线程对共享资源按顺序进行原子操作。

用一种简单的加锁方法来控制对共享资源的原子操作。

互斥锁只有两种状态:

上锁和解锁,可以把互斥锁看作某种意义上的全局变量。

同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作。

若其他线程希望访问一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。

互斥锁保证每个线程对共享资源按序进行原子操作。

2.程序流程设计

 

 

3.部分程序代码注释(关键函数或代码)

……

/*thread_mutex.c*/

#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%dlockfailed\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("Createtreadssuccess\nWaitingforthreadstofinish...\n");

for(no=0;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.结果分析

……

通过运行结果可以看出,使用了互斥锁以后,原本独立的无序的多个线程能够按顺序执行。

并且执行顺序和创建线程的顺序相同。

 

实验三(P291:

11-thread_sem.c)

1、软件功能描述

由于线程共享进程的资源和地址空间,因此在对这些资源进行操作的时候,必须考虑到线程间资源访问的同步与互斥问题。

本实验利用信号量同步机制实现3个线程之间的有序执行。

2、程序流程设计

 

 

3.部分程序代码注释(关键函数或代码)

……

/*thread_sem.c*/

#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("Createtreadssuccess\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、软件功能描述

通常首先调用pthread_attr_init()函数进行初始化,之后再调用相应属性设置函数,最后调用pthread_attr_destroy()函数对分配的属性结构指针进行清理和回收。

设置绑定属性的函数为pthread_attr_setscope(),设置线程分离属性的函数为pthread_attr_setdetachstate(),获取线程优先级的函数pthread_attr_getschedparam()和设置线程优先级的函数pthread_attr_setschedparam。

在设置完这些属性后,就可以调用pthread_create()函数来创建线程了。

2、程序流程设计

 

3.部分程序代码注释(关键函数或代码)

……

/*thread_attr.c*/

#include

#include

#include

#defineTHREAD_NUMBER1

#defineREPEAT_NUMBER3

#defineDELAY_TIME_LEVELS10.0

intfinish_flag=0;

void*thrd_func(void*arg)

{

intdelay_time=0;

intcount=0;

printf("Threadisstarting\n");

for(count=0;count

{

delay_time=(int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX))+1;

sleep(delay_time);

printf("\tThread:

job%ddelay=%d\n",count,delay_time);

}

printf("Threadfinished\n");

finish_flag=1;

pthread_exit(NULL);

}

intmain(void)

{

pthread_tthread;

pthread_attr_tattr;

intres=0;

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(&thread,&attr,thrd_func,NULL);

if(res!

=0)

{

printf("Createthreadfailed\n");

exit(res);

}

pthread_attr_destroy(&attr);

printf("Createtreadsuccess\n");

while(!

finish_flag)

{

printf("Waitingforthreadtofinish...\n");

sleep

(2);

}

return0;

}

……

4.编译、运行方法及结果(抓屏)

5.结果分析

……

程序运行成功,使用gccthread_attr.c-pthread-0test1编译后z再./test1代码成功运行,从结果可以看出线程在运行结束后就收回了系统资源,并且释放了内存。

实验五(p298:

11-producer-customer.c)

1、软件功能描述

建立两个有限缓存区和两个线程:

生产者和消费者,他们不停的把产品放入缓存区和从缓存区拿走产品。

一个生产者在缓存区满的时候必须等待,一个消费者在缓存区空的时候也必须等待。

另外,因为缓存区是临界资源,所以生产者和消费者之间必须互斥执行,在该程序中使用有名管道来模拟有限缓存区,并用信号量来解决“生产者和消费者”同步和互斥问题。

2、程序流程设计

 

3.部分程序代码注释(关键函数或代码)

……

/*producer-customer.c*/

#include

#include

#include

#include

#include

#include

#include

#include

#defineMYFIFO"myfifo"

#defineBUFFER_SIZE3/*缓冲区的单元数*/

#defineUNIT_SIZE5/*每个单元的大小*/

#defineRUN_TIME30/*运行时间*/

#defineDELAY_TIME_LEVELS5.0/*周期的最大值*/

void*producer(void*arg);

void*customer(void*arg);

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);

/*P操作信号量avail和mutex*/

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.Pleasetrylater\n");

}

}

else

{

printf("Write%dtotheFIFO\n",real_write);

}

/*V操作信号量full和mutex*/

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);

/*P操作信号量full和mutex*/

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);

/*V操作信号量avail和mutex*/

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;

}

/*初始化互斥信号量为1*/

ret=sem_init(&mutex,0,1);

/*初始化avail信号量为N*/

ret+=sem_init(&avail,0,BUFFER_SIZE);

/*初始化full信号量为0*/

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 育儿知识

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1