linux下利用互斥实现线程访问共享资源含源文件.docx

上传人:b****4 文档编号:3732854 上传时间:2022-11-25 格式:DOCX 页数:30 大小:586.04KB
下载 相关 举报
linux下利用互斥实现线程访问共享资源含源文件.docx_第1页
第1页 / 共30页
linux下利用互斥实现线程访问共享资源含源文件.docx_第2页
第2页 / 共30页
linux下利用互斥实现线程访问共享资源含源文件.docx_第3页
第3页 / 共30页
linux下利用互斥实现线程访问共享资源含源文件.docx_第4页
第4页 / 共30页
linux下利用互斥实现线程访问共享资源含源文件.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

linux下利用互斥实现线程访问共享资源含源文件.docx

《linux下利用互斥实现线程访问共享资源含源文件.docx》由会员分享,可在线阅读,更多相关《linux下利用互斥实现线程访问共享资源含源文件.docx(30页珍藏版)》请在冰豆网上搜索。

linux下利用互斥实现线程访问共享资源含源文件.docx

linux下利用互斥实现线程访问共享资源含源文件

“计算机操作系统”课程设计大作业

一、实验题目:

linux下利用互斥实现线程访问共享资源

二、实验目的:

掌握线程创建和终止,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的通信。

三、实验内容

事先了解操作系统中经典的生产者-消费者问题,安装linux虚拟机(可以用virtualbox或者vmware软件)。

在linux下创建三个生产者线程(P1,P2,P3)和一个消费者线程(C1),生产者和消费者线程共享一个长度为2KB的环型公共缓冲区,生产者向缓冲区写入消息,消费者从缓冲区中取走消息显示到屏幕。

只要缓冲区未满,生产者可将消息送入缓冲区;只要缓冲区未空,消费者可从缓冲区取走一个消息。

每个消息具下列结构格式:

消息长度(1个字节),消息内容(n个字节)。

每个生产者每隔2秒生产一个消息加入缓冲区,并把消息产生时间和内容记录在一个文本文件中。

P1每次生产的数据为26个大写字母,P2每次生产的数据为26个小写字母,P3每次生产的数据为10个阿拉伯数字。

消费者C1每隔3秒读取缓冲区中的一个消息并将消息内容显示到屏幕上。

用两种方法(不采线程用互斥和采用线程互斥技术)编写上述功能的程序,对比两种程序运行结果有何区别?

不采线程用互斥时存在什么问题?

备注:

编程中用到的函数

创建线程函数:

pthread_create

互斥锁初始化:

pthread_mutex_init

互斥锁加锁:

pthread_mutex_lock

互斥锁解锁:

pthread_mutex_unlock

四、实验要求:

每人完成一份大作业实验报告。

报告分设计思想、数据定义、处理流程、源程序、运行结果截图、设计体会等部分。

1)给出数据定义和详细说明;

2)给出实现思想和设计流程;

3)调试完成源程序;

4)屏幕观察运行结果;

5)总结自己的设计体会;

编程语言及操作系统平台不限。

五、提交内容

本大作业每个人必须单独完成。

最后需提交的内容包括:

源程序(关键代码需要注释说明)、可运行程序、算法思路及流程图、心得体会。

大作业必须以WORD附件的形式提交。

大作业严禁抄袭。

发现抄袭一律以不及格论。

大作业内容要完整,一定要有算法思路、流程图、心得体会、运行输出信息截屏等内容,如果只提交源代码则大作业成绩记为不合格。

2016-10-20

 

linux下利用互斥实现线程访问共享资源

一、原理的理解

生产者-消费者问题是一个经典的线程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。

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

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

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

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

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

多个生产/消费者在有界缓冲上操作。

它利用N个字节的共享内存作为有界循环缓冲区,利用写一字符模拟放一个产品,利用读一字符模拟消费一个产品。

当缓冲区空时消费者应阻塞睡眠,而当缓冲区满时生产者应当阻塞睡眠。

一旦缓冲区中有空单元,生产者线程就向空单元中入写字符,并报告写的内容和位置。

一旦缓冲区中有未读过的字符,消费者线程就从该单元中读出字符,并报告读取位置。

生产者不能向同一单元中连续写两次以上相同的字符,消费者也不能从同一单元中连续读两次以上相同的字符。

二、完成步骤

1、思路分析

本作业是完善课件上的线程综合实例的练习生产者-消费者问题,重构这个程序的框架,完成性能分析,使之进一步理解掌握Linux下线程的同步、通信以及互斥和多线程的安全问题。

一般情况下,解决互斥方法常用信号量和互斥锁,即semaphore和mutex,而解决这个问题,多采用一个类似资源槽的结构,每个槽位标示了指向资源的指针以及该槽位的状态,生产者和消费者互斥查询资源槽,判断是否有产品或者有空位可以生产,然后根据指针进行相应的操作。

同时,为了告诉生产者或者消费者资源槽的情况,还要有一个消息传送机制,无论是管道还是线程通信。

然而,本次试验有几个特殊的要求:

A、循环缓冲。

B、除了stderr,stdout等外,只用小于2个的互斥锁、

C、放弃资源槽分配机制,采用额外的数据结构。

D、生产者一直持续生产,形成生产消费的良性循环。

首先,使用一个互斥锁,意味着资源槽机制就不能使用了。

因为资源槽虽以用一个互斥锁完成,但是需要有额外的通信,如果使用管道通信,则管道也必须是互斥,这就不满足1个互斥锁的要求。

其次,要求生产者一直生产,这就否定了另外一种方法:

消费者、生产者的位置均平等,消费者消费的时候生产者不能生产,生产者生产的时候消费者不能消费。

因此,就需要采用A要求,也就是循环链表的形式。

为了保证互斥要求,需要定义一个数据结构,这个数据结构包含两个指针,一个读一个写,同时有一个资源数目量,告诉生产者和消费者是否可以生产或者消费。

由于该数据结构很小,因而可以对此结构互斥访问。

同时,对于每组数据,都有一个标志位,表示此组数据是否被占用,生产者和消费者均可以先占用此位置然后完成相应的操作。

当消费者互斥访问此结构时,首先判断是否有数据可以取,如果没有,直接等待,若有数据可取,先更改标志位占用此数据,并将资源数目-1。

然后交出互斥,把数据拷贝到自己缓冲区内,清空数据。

当生产者访问时,首先判断有没有空位可以生产,如果没有,直接等待,若有数据可以生产,先判断该位是否被占用,如果没被占用,则占用此位置进行生产。

生产完成后,将占用位改为未占用,同时将资源数目+1。

这个过程可以如图所示:

2、重要函数和数据结构

(1)数据结构

#defineN5//生产者的数目

#defineN215//消费者数目

#defineM20//缓冲数目

#definedebug0//调试模式

#definenowait1//是否添加额外等待

pthread_mutex_tmutex;//互斥信号量

intprod_id=0;//生产者id

intproc_id=0;//消费者id

//成功以及失败次数计数

intSucc[N+N2];

intFail[N+N2];

//用于生产的填充数据

chardt[30]="aaaaaaaaaabbbbbbbbbbcccccccccc";

inttoexit=0;//退出标记

//共用数据区

structdata_struc

{

intOccupied;//该位置是否被占用无论生产还是消费

chard[1024];//数据

structdata_struc*nx;//下一个指针

};

//互斥量

structmtx

{

structdata_struc*rd_p;

structdata_struc*wr_p;

intcnt;//产品数量

};

structmtx*mymutex;

(2)函数说明

voidprintinfo();//调试函数,打印公用数据区的内容和状态

voidCreate_Empty_DS();//初始化循环链表

void*buy();//消费者

void*sell();//生产者

void*Recount();//数据统计,同时控制程序自动退出

3、程序流程图

A、主函数

B、统计线程

C、生产者线程

D、消费者线程

三、实验数据

1、程序运行截图

虚拟机:

VMwareWorkstation7.0,win7;硬件:

i3,2GDDR1333;编译:

gccproduct.c–pg–lpthread;报告生成:

gprof–b。

运行时截图:

CPU占用情况(无额外等待):

2、原始数据

由于程序要求使用gprof进行分析,而在机器配置较好的情况下,使用gprof可能分析不出每个函数执行时间,甚至连函数都分析不全,因而在实际代码中添加了一些空循环来增加cpu占用。

为了更便于观察,首先假设如下场景:

消费者、生产者在执行各自动作前,均usleep

(1),同时,消费者在成功消费之后,也会usleep(3)来为其他消费者让位。

同时,也将测试没有任何等待的数据。

程序内有一计时线程,每个一秒会显示一次生产消费情况,当60秒后程序自动退出,从而保存数据已被分析。

生产者数量

1

消费者数量

1

缓冲长度

20

额外等待

CPU占用

<0.3%

函数分析情况

无法分析到消费者、生产者线程

程序运行情况

生产者:

#1成功次数:

12243失败次数:

12213

消费者:

#1成功次数:

12223失败次数:

0

生产者数量

1

消费者数量

1

缓冲长度

20

额外等待

CPU占用

>97%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

54.592.082.08buy

45.413.811.73sell

0.003.810.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.26%of3.81seconds

index%timeselfchildrencalledname

[1]54.62.080.00buy[1]

-----------------------------------------------

[2]45.41.730.00sell[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[1]buy[2]sell

程序运行情况

生产者:

#1成功次数:

21260失败次数:

1146117485

消费者:

#1成功次数:

21240失败次数:

1151177763

生产者数量

1

消费者数量

5

缓冲长度

20

额外等待

CPU占用

<0.3%

函数分析情况

无法分析到消费者、生产者线程

程序运行情况

生产者:

#1成功次数:

24829失败次数:

0

消费者:

#1成功次数:

4900失败次数:

15102

消费者:

#2成功次数:

5261失败次数:

14386

…..

消费者:

#5成功次数:

5069失败次数:

14752

生产者数量

1

消费者数量

5

缓冲长度

20

额外等待

CPU占用

>97%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

85.292.902.90buy

14.713.400.50sell

0.003.400.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.29%of3.40seconds

index%timeselfchildrencalledname

[1]85.32.900.00buy[1]

-----------------------------------------------

[2]14.70.500.00sell[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[1]buy[2]sell

程序运行情况

生产者:

#1成功次数:

10800失败次数:

362944304

消费者:

#1成功次数:

1980失败次数:

368988095

消费者:

#5成功次数:

2560失败次数:

391801113

生产者数量

3

消费者数量

10

缓冲长度

20

额外等待

CPU占用

约4%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

94.081.591.59sell

5.921.690.10buy

0.001.690.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.59%of1.69seconds

index%timeselfchildrencalledname

[1]94.11.590.00sell[1]

-----------------------------------------------

[2]5.90.100.00buy[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[2]buy[1]sell

程序运行情况

生产者:

#1成功次数:

161677失败次数:

0

生产者:

#2成功次数:

161412失败次数:

0

生产者:

#3成功次数:

161535失败次数:

0

消费者:

#1成功次数:

44264失败次数:

75030

消费者:

#2成功次数:

47878失败次数:

67808

消费者:

#3成功次数:

47805失败次数:

67967

……

消费者:

#10成功次数:

45942失败次数:

71664

生产者数量

3

消费者数量

10

缓冲长度

20

额外等待

CPU占用

>97%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

77.282.962.96buy

22.723.830.87sell

0.003.830.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.26%of3.83seconds

index%timeselfchildrencalledname

[1]77.32.960.00buy[1]

-----------------------------------------------

[2]22.70.870.00sell[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[1]buy[2]sell

程序运行情况

生产者:

#1成功次数:

4640失败次数:

174184091

生产者:

#2成功次数:

4000失败次数:

179724333

生产者:

#3成功次数:

4120失败次数:

170018676

消费者:

#1成功次数:

1280失败次数:

182205853

消费者:

#2成功次数:

1340失败次数:

173044281

…..

消费者:

#9成功次数:

1020失败次数:

166877134

消费者:

#10成功次数:

1380失败次数:

164803475

生产者数量

5

消费者数量

20

缓冲长度

40

额外等待

CPU占用

约9%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

96.374.254.25sell

3.634.410.16buy

0.004.410.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.23%of4.41seconds

index%timeselfchildrencalledname

[1]96.44.250.00sell[1]

-----------------------------------------------

[2]3.60.160.00buy[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[2]buy[1]sell

程序运行情况

生产者:

#1成功次数:

139689失败次数:

0

生产者:

#2成功次数:

139235失败次数:

0

….

生产者:

#5成功次数:

137801失败次数:

0

消费者:

#1成功次数:

25922失败次数:

96488

消费者:

#2成功次数:

39009失败次数:

70402

消费者:

#3成功次数:

39645失败次数:

69154

…..

消费者:

#20成功次数:

33775失败次数:

80811

生产者数量

5

消费者数量

20

缓冲长度

40

额外等待

CPU占用

>97%

函数分析情况

%cumulativeselfselftotal

timesecondssecondscallsTs/callTs/callname

80.292.812.81buy

19.713.500.69sell

0.003.500.0010.000.00Create_Empty_DS

Callgraph

granularity:

eachsamplehitcovers4byte(s)for0.29%of3.50seconds

index%timeselfchildrencalledname

[1]80.32.810.00buy[1]

-----------------------------------------------

[2]19.70.690.00sell[2]

-----------------------------------------------

0.000.001/1main[8]

[3]0.00.000.001Create_Empty_DS[3]

-----------------------------------------------

Indexbyfunctionname

[3]Create_Empty_DS[1]buy[2]sell

程序运行情况

生产者:

#1成功次数:

4120失败次数:

81703999

….

生产者:

#5成功次数:

4200失败次数:

91874644

消费者:

#1成功次数:

1080失败次数:

83483253

消费者:

#2成功次数:

1240失败次数:

85970149

消费者:

#3成功次数:

1360失败次数:

106265813

消费者:

#4成功次数:

960失败次数:

82522392

消费者:

#5成功次数:

1360失败次数:

93462020

消费者:

#6成功次数:

1160失败次数:

91337608

消费者:

#7成功次数:

1520失败次数:

102954859

消费者:

#8成功次数:

1080失败次数:

91363902

消费者:

#9成功次数:

760失败次数:

105319175

消费者:

#10成功次数:

1320失败次数:

102144117

消费者:

#11成功次数:

720失败次数:

90933552

消费者:

#12成功次数:

1120失败次数:

90537228

消费者:

#13成功次数:

920失败次数:

90670465

消费者:

#14成功次数:

840失败次数:

109153419

消费者:

#15成功次数:

1320失败次数:

91949204

消费者:

#16成功次数:

960失败次数:

80094023

消费者:

#17成功次数:

1120失败次数:

81866777

消费者:

#18成功次数:

1000失败次数:

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

当前位置:首页 > 求职职场 > 简历

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

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