中南大学Linux第四次实验报告Word文档格式.docx

上传人:b****3 文档编号:18439960 上传时间:2022-12-16 格式:DOCX 页数:12 大小:125.08KB
下载 相关 举报
中南大学Linux第四次实验报告Word文档格式.docx_第1页
第1页 / 共12页
中南大学Linux第四次实验报告Word文档格式.docx_第2页
第2页 / 共12页
中南大学Linux第四次实验报告Word文档格式.docx_第3页
第3页 / 共12页
中南大学Linux第四次实验报告Word文档格式.docx_第4页
第4页 / 共12页
中南大学Linux第四次实验报告Word文档格式.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

中南大学Linux第四次实验报告Word文档格式.docx

《中南大学Linux第四次实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《中南大学Linux第四次实验报告Word文档格式.docx(12页珍藏版)》请在冰豆网上搜索。

中南大学Linux第四次实验报告Word文档格式.docx

2.实验环境

已安装Linux操作系统的微机一台

3.实验内容

问题描述:

一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。

假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;

只要缓冲池未空,消费者可从缓冲池取走一个消息。

功能要求:

根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放数据、取数据等过程。

生产者功能描述

在同一个进程地址空间内执行的两个线程。

生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。

当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

消费者功能描述

消费者线程从缓冲区中获得物品,然后释放缓冲区。

当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

程序结构图:

4.具体设计要求及有关说明

A、主函数

B、统计线程

C、生产者线程

D、消费者线程

(1)有2个生产者线程,分别为P1、P2;

有2个消费者进程,分别是C1、C2;

缓冲区单元个数N=15;

(2)不同的生产者可生产不同的产品(比如字母、数字、符号);

不同的消费者可有不同的消费方式(比如“显示”、“打印”、“拼接成字符串”、“改变大小写”等)。

自己可任意定义。

(3)使用Linux线程同步:

mutex、conditionvirable和semaphore完成上述问题。

(4)程序源代码和实验结果如下:

#include<

pthread.h>

stdio.h>

semaphore.h>

sem_tblank_number,product_number;

pthread_cond_tfull=PTHREAD_COND_INITIALIZER;

pthread_cond_tempty=PTHREAD_COND_INITIALIZER;

pthread_mutex_tlock=PTHREAD_MUTEX_INITIALIZER;

#defineNUM15

structP_Queue{

charproductc[NUM];

intfront,rear;

intnum;

};

void*producer1(void*arg)

{structP_Queue*q;

q=(structP_Queue*)arg;

while

(1){

pthread_mutex_lock(&

lock);

while(q->

num==NUM){

pthread_cond_wait(&

full,&

}

sem_wait(&

blank_number);

charc=rand()%26+'

a'

;

q->

rear=(q->

rear+1)%NUM;

productc[q->

rear]=c;

printf("

缓冲池1的产品是:

%c\n"

q->

rear]);

num++;

产品数量:

%d\n"

num);

sem_post(&

product_number);

if(q->

num==1){

pthread_cond_signal(&

empty);

pthread_mutex_unlock(&

sleep(rand()%2);

}

void*producer2(void*arg)

{

structP_Queue*q;

num==NUM){

A'

缓冲池2的产品是:

void*consumer1(void*arg)

num==0){

empty,&

front=(q->

front+1)%NUM;

charc=q->

front];

front]='

'

num--;

消费者1显示内容:

%c\n"

c);

num==NUM-1){

full);

void*consumer2(void*arg)

num==0){

chard=0;

if(c>

=65&

&

c<

=90)

{d=c+32;

else

{d=c-32;

消费者2更改大小写:

%c---%c\n"

c,d);

intmain(intargc,char*argv[])

q=(structP_Queue*)malloc(sizeof(structP_Queue));

front=q->

rear=NUM-1;

num=0;

pthread_tpid1,cid1,pid2,cid2;

sem_init(&

blank_number,0,NUM);

product_number,0,0);

pthread_create(&

pid1,NULL,producer1,(void*)q);

cid1,NULL,consumer1,(void*)q);

pid2,NULL,producer2,(void*)q);

cid2,NULL,consumer2,(void*)q);

pthread_join(pid1,NULL);

pthread_join(cid1,NULL);

pthread_join(pid2,NULL);

pthread_join(cid2,NULL);

sem_destroy(&

程序运行结果如下:

5.实验总结

1.写出Linux系统中线程同步实现机制有哪些?

怎样使用?

Linux系统中线程同步实现机制通过对互斥变量Mutex、信号灯Semophore、条件变量Conditions的设置实现线程的同步。

(1)互斥变量(Mutex)

互斥变量的类型为pthread_mutex_t。

可以声明多个互斥量。

在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。

pthread_mutex_init的格式如下:

intpthread_mutex_init(pthread_mutex_t*mutex,constpthread_mutex-attr_t*mutexattr);

第一个参数mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。

在创建该互斥量之后,你便可以使用它了。

要得到互斥量,你需要调用下面的函数:

intpthread_mutex_lock(pthread_mutex_t*mutex);

该函数用来给互斥量上锁,也就是等待操作。

互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就会阻塞在这个操作上。

如果在此之前该互斥量已经被其他线程上锁,那么该操作将会一直阻塞在这个地方,直到获得该锁为止。

在得到互斥量后,就可以进入关键代码区了。

同样,在操作完成后,你必须调用intpthread_mutex_unlock(pthread_mutex_t*mutex);

函数来给互斥量解锁,也就是释放。

这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。

(2)信号灯机制(Semaphore)

信号灯其实就是一个计数器,也是一个整数。

每一次调用wait操作将会使semaphore值减一,而如果semaphore值已经为0,则wait操作将会阻塞。

每一次调用post操作将会使semaphore值加一。

生产者线程在每次往缓冲池中添加产品后调用post操作,信号灯值会加一。

这样阻塞的工作线程就会停止阻塞,继续往下执行。

信号灯的类型为sem_t。

在声明后必须调用sem_init()。

需要传递两个参数,第一个参数就是你之前声明的sem_t变量,第二个必须为0。

当你不再需要信号灯时,你必须调用sem_destroy()来释放资源。

等待信号灯的操作为sem_wait()。

和互斥量一样,等待信号灯也有一个非阻塞的操作,sem_trywait()。

该操作在没有信号灯的时候返回EAGAIN。

(3)条件变量(Conditions)

如果现在在等待一个信号。

如果该信号被设置,则继续运行。

如果没有条件变量,它将会不停的去查询该信号是否被设置,这样就会浪费大量的处理机。

而通过使用条件变量,我们就可以将等待信号的线程阻塞,直到有信号的时候再去唤醒它。

条件变量的类型是pthread_cond_t。

a.声明pthread_cond_t变量后,调用pthread_cond_init()函数,第一个参数为之前声明的变量。

第二个参数在Linux中不起作用。

b.声明一个pthread_mutex_t变量,并调用pthread_mutex_init()初始化。

c.调用pthread_cond_signal()发出信号。

如果此时有线程在等待该信号,那么该线程将会唤醒。

如果没有,该信号就会别忽略。

d.如果想唤醒所有等待该信号的线程,调用pthread_cond_broadcast()。

e.调用pthread_cond_wait()等待信号。

如果没有信号,线程将会阻塞,直到有信号。

该函数的第一个参数是条件变量,第二个参数是一个mutex。

在调用该函数之前必须先获得互斥量。

如果线程阻塞,互斥量将立刻会被释放。

2.实验中遇到了哪些问题,是怎样解决的?

在实验过程中还遇到了一些问题,在函数编译时,我输入命令gcc–oshiyan2shiyan2.c时系统m没有执行,后来请教同学后将命令改为:

gccshiyan2.c-lpthread后运行成功。

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

当前位置:首页 > 医药卫生 > 基础医学

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

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