📄 设计报告.txt
字号:
一、基本信息
实践题目:同步对象实现P、V操作
二、实践内容简要描述
实践目标:
用Win32提供的同步对象实现P、V操作,并解决任务4中有限缓冲区问题
实践内容:
用同步对象实现P、V操作解决一下问题:
写一个线程实现C/C++语言程序:一些线程负责找出某个数据范围的素数,并放到一个数组中,另一些线程负责将数组中的素数按次序取出,并显示出来。显示过的数据要从数组中删除。要求定义一个全局变量的数组:int prime[9]用于存放找到的待显示的素数。
三、实践报告主要内容
设计思路:
实现P、V操作用了binary semaphore来实现,
wait操作的实现
Wait(s1);
c--;
if(c<0){
signal(s1);
wait(s2);
}
signal(s1);
signal操作的实现:
wait(s1);
c++;
if(c<=0)
signal(s2);
else
signal(s1);
线程同步仍采用了生产者-消费者算法。
P、V操作用了一个返回值,为0时表示超时,为1表示等待成功。
主要数据结构:
线程信息结构体:
int searchCount = 0; //已开线程数
int displayCount = 0; //已开线程数
CRITICAL_SECTION my_section;
HANDLE h_semaphore_s1_e = CreateSemaphore(NULL, 1, 1, "Bin_S1_Empty"); //Empty的S1
HANDLE h_semaphore_s2_e = CreateSemaphore(NULL, 0, 1, "Bin_S2_Empty"); //Empty的S2
HANDLE h_semaphore_s1_f = CreateSemaphore(NULL, 1, 1, "Bin_S1_Full"); //Full的S1
HANDLE h_semaphore_s2_f = CreateSemaphore(NULL, 0, 1, "Bin_S2_Full"); //Full的S2
int Count_Empty; //Empty计数器
int Count_Full; //Full计数器
struct ThreadInfo
{
int serial;
char command;
int num_from;
int num_to;
};
int prime[9];
void GetCommand( char* file );
void thd_display(void* p);
void thd_search(void* p);
BOOL IsPrime(int num); //用于判断是否为素数
int GetUsed(int num[9]); //用于获得剩余空间
void P(LPCTSTR lpcstr,int &count); //P 操作
void V(LPCTSTR lpcstr,int &count); //V 操作
主要代码分析:
int wait(int *,HANDLE Event[]); // binary semaphore实现的P 操作
int signal(int *,HANDLE Event[]); // binary semaphore实现的V 操作
四、实践结果
基本数据:
源程序代码行数 完成实践投入的总时间 资料查阅时间 编程调试时间 源程序文件
413 1小时 0.5小时 0.5小时 ex5.cpp
测试数据设计:
1.“ex4.dat”文件内容测试结果同ex4:
2.自设测试数据
1 w 10 100
2 w 1 10
3 W 2 20
4 D 20 0
5 D 3 0
测试结果分析:
对应于数据的运行结果:
Reader Priority:
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 2 begins to write the date .
Search thread 2 finish writing the date .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Search thread 2 begins to write the date .
Search thread 2 finish writing the date .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "11".
Display thread 4 finishes outputting prime num .
Display thread 5 begins to output prime num .
----------Display thread 5 output the prime num "13".
Display thread 5 finishes outputting prime num .
Search thread 2 begins to write the date .
Search thread 2 finish writing the date .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "7".
Display thread 4 finishes outputting prime num .
Display thread 5 begins to output prime num .
----------Display thread 5 output the prime num "7".
Display thread 5 finishes outputting prime num .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "11".
Display thread 4 finishes outputting prime num .
Display thread 5 begins to output prime num .
----------Display thread 5 output the prime num "17".
Display thread 5 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "23".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "31".
Display thread 4 finishes outputting prime num .
Search thread 3 begins to write the date .
Search thread 3 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "19".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "37".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "41".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "43".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "47".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "53".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "59".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "61".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "67".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "71".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "73".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "79".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "83".
Display thread 4 finishes outputting prime num .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "13".
Display thread 4 finishes outputting prime num .
Display thread 4 begins to output prime num .
----------Display thread 4 output the prime num "29".
Display thread 4 finishes outputting prime num .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
Search thread 1 begins to write the date .
Search thread 1 finish writing the date .
All search and display thread have finished Operating.
The array at last.
89 97 0 19 3 3 5 5 17
Press any key to finish this Program.
Thank you test this Program!
程序运行过程中,线程1、线程2、线程3为找素数线程,线程4、线程5负责显示,它们均交叉访问临界区,程序运行结果完全正确。
五、实践体会
该实验与实验四相比,只是用软件的方法来实现内核对象的功能,只须细心就能顺利完成任务。
通过实验我基本了解了P、V操作的具体实现,以及有限缓冲区问题的解决方法。
七、参考文献
1、MSDN
2、《操作系统概念(第六版 影印版)》,Abraham Silberschatz、Peter Baer Galvin、Greg Gagne,
高等教育出版社
附:源程序部分关键代码
void P(LPCTSTR lpcstr,int &count)
{
HANDLE h_s1,h_s2;
if(strcmp(lpcstr,"Empty") == 0)
{
h_s1=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S1_Empty");
h_s2=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S2_Empty");
}
else if(strcmp(lpcstr,"Full") == 0)
{
h_s1=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S1_Full");
h_s2=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S2_Full");
}
WaitForSingleObject(h_s1, INFINITE);
count--;
if (count < 0)
{
ReleaseSemaphore(h_s1, 1, NULL);
WaitForSingleObject(h_s2, INFINITE);
}
ReleaseSemaphore(h_s1, 1, NULL);
CloseHandle(h_s1);
CloseHandle(h_s2);
}
void V(LPCTSTR lpcstr,int &count)
{
HANDLE h_s1,h_s2;
if(strcmp(lpcstr,"Empty") == 0)
{
h_s1=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S1_Empty");
h_s2=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S2_Empty");
}
else if(strcmp(lpcstr,"Full") == 0)
{
h_s1=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S1_Full");
h_s2=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,"Bin_S2_Full");
}
WaitForSingleObject(h_s1, INFINITE);
count++;
if (count <= 0)
{
ReleaseSemaphore(h_s2, 1, NULL);
}
else
{
ReleaseSemaphore(h_s1, 1, NULL);
}
CloseHandle(h_s1);
CloseHandle(h_s2);
}
任务六 LINUX下以原生方式查看软盘信息
一、基本信息
实践题目:在LINUX下以原生(raw)方式查看软盘的信息
二、实践内容简要描述
实践目标:
熟悉Linux操作系统下的基本操作及其程序设计的基本方法。
学会在LINUX下使用原生方式查看软盘上的数据信息。
实践内容:
在LINUX下使用原生方式查询并显示目前磁盘的以下信息:
-每扇区字节数
-每磁道扇区数
-每柱面的磁道数(磁头数)
三、实践报告主要内容
设计思路:
只要正确定位文件的读取位置并确定所需读取的字节数便可以正确读取软盘上的数据,先用open函数以只读方式打开软盘,再用lseek定位读取位置,然后用read读取相应字节的数据即可。
主要数据结构:
int fd; //文件描述符
size_t num_read;
int bytes_per_sector = 0; //每扇区字节数
int sectors_per_track = 0; //每磁道扇区数
int number_of_surface = 0; //每柱面的磁道数(磁头数)
int * pi; //指向文件缓冲区的指针
pi = &bytes_per_sector;
pi = §ors_per_track;
pi = &number_of_surface;
主要代码分析: 详见代码注释。
四、实践结果
基本数据:
源程序代码行数 完成实践投入的总时间 资料查阅时间 编程调试时间 源程序文件
43 0.5小时 0.4小时 0.1小时 ex6.cpp
测试数据设计:
3.5寸软盘一张。
测试结果分析:
程序运行结果为:
Bytes per sector: 512
Sectors per track: 18
Number of surfaces:: 2
程序运行结果完全正确。
五、实践体会
以原生方式读取磁盘信息时,将磁盘当作一个文件打开,要正确定位文件的读取位置,并确定读取字节数,这样便能从中读取相应数据。通过实验,了解了软盘上BOOT的布局,并熟悉了Linux操作系统下程序设计的基本方法和基本操作。
六、参考文献
1、《Linux基础教程》,黄庆生 吴振华 苏哲 编著,人民邮电出版社
附:源程序代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
//每扇区字节数 0x0b-0x0c 11 - 12
//每磁道扇区数 0x18-0x19 24 - 25
//每柱面的磁道数 0x1a-0x1b 26 – 27
int fd;
size_t num_read;
int bytes_per_sector = 0;
int sectors_per_track = 0;
int number_of_surface = 0;
int * pi;
fd = open("/dev/fd0", O_RDONLY);
pi = &bytes_per_sector;
lseek(fd,(off_t)11,SEEK_SET);
num_read = read(fd,(void *)pi,(size_t)2);
printf("Bytes per sector: %d\n",bytes_per_sector);
pi = §ors_per_track;
lseek(fd,(off_t)24,SEEK_SET);
num_read = read(fd,(void *)pi,(size_t)2);
printf("Sectors per track: %d\n",sectors_per_track);
pi = &number_of_surface;
lseek(fd,(off_t)26,SEEK_SET);
num_read = read(fd,(void *)pi,(size_t)2);
printf("Number of surfaces: %d\n",number_of_surface);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -