Files
OS/lab1/report/report.tex
2025-04-22 11:39:53 +08:00

174 lines
7.1 KiB
TeX
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
\documentclass[12pt, a4paper]{article}
\usepackage[UTF8]{ctex}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amssymb}
\usepackage{enumitem}
\usepackage{float}
\usepackage{graphicx}
\usepackage{extarrows}
\usepackage{booktabs}
\usepackage{diagbox}
\usepackage{siunitx}
\usepackage{subcaption}
\usepackage{fontspec}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{siunitx}
\usepackage[ruled,vlined]{algorithm2e}
\sisetup{
group-separator={,},
}
\definecolor{vscodeBlue}{RGB}{0,0,255} % 关键字/语句
\definecolor{vscodeRed}{RGB}{163,21,21} % 字符串
\definecolor{vscodeGreen}{RGB}{0,128,0} % 注释
\newfontfamily\codefont{Fira Code}
\lstset{
basicstyle = \footnotesize\codefont,
% ---
tabsize = 4,
showstringspaces = false,
numbers = left,
numberstyle = \codefont,
% ---
breaklines = true,
captionpos = t,
% ---
frame = l,
flexiblecolumns,
commentstyle=\color{vscodeGreen}, % 注释样式
keywordstyle=\color{vscodeBlue}, % 关键字样式
stringstyle=\color{vscodeRed}, % 字符串样式
rangebeginprefix = //\ BEGIN_LST_,
rangeendprefix = //\ END_LST_
}
\renewcommand{\qedsymbol}{}
\lstMakeShortInline|
\geometry{a4paper,scale=0.8}
\allowdisplaybreaks[4] %允许公式跨页
\setenumerate[1]{label=\arabic{*}. }
\setenumerate[2]{label=(\arabic{*})}
\title{\Huge{{\bf 操作系统大作业实验1报告}}}
\author{高艺轩 2022010639}
\date{}
\begin{document}
\maketitle
\section{实验目的}
\begin{enumerate}
\item 通过对进程间通信同步/互斥问题的编程实现加深理解信号量和P、V操作的原理
\item 对Windows或Linux涉及的几种互斥、同步机制有更进一步的了解
\item 熟悉Windows或Linux中定义的与互斥、同步有关的函数。
\end{enumerate}
\section{实验题目}
本次实验选择的题目是“银行柜员服务问题”。
\section{问题描述}
银行有 n 个柜员负责为顾客服务,顾客进入银行先取一个号码,然后等着叫号。当某个柜员空闲下来,就叫下一个号。
编程实现该问题,用 P、V 操作实现柜员和顾客的同步。
\section{思路与程序结构}
这个问题的场景实际上就是一个典型的生产者-消费者问题。把顾客看作资源柜员看作消费者那么顾客在不停地到来就是生产者生产的过程柜员服务即为消费者。因此所要竞争的主要内容即为“正在等待的顾客”由柜员对顾客数执行P由到来的顾客对顾客数执行V另外为了存储正在等待的顾客用于在顾客线程和柜员线程中交换对应的顾客信息需要维护一个队列以及对应的互斥锁在访问前使用P原语锁定访问结束后使用V原语释放。
为了便于观察现象和验证程序运行,本次实验中我将时间刻间隔设置为\SI{200}{ms}
具体来讲,在全局设置代表待服务的顾客数量的信号量:
\lstinputlisting[language=c++, linerange=COUNT_SEM]{../banker.cpp}
同时设置一个正在等待服务的客户队列,并用一个互斥锁保护它:
\lstinputlisting[language=c++, linerange=CUS_Q]{../banker.cpp}
在设置好全局变量后,分别实现柜员和顾客。对于柜员,每到一个时间刻,如果正在服务的客户还没有服务完,那么就继续服务;如果处于空闲状态,则尝试执行|P(customer_num_sem)|获得一个新的客户。如果能获得客户,则进一步锁定客户队列,取出队头进行服务,再解锁客户队列。伪代码如下:
\begin{algorithm}[htbp]
\caption{Server Procedure}
\SetKwFunction{FMain}{Teller}
\SetKwProg{Fn}{Function}{:}{}
\Fn{\FMain{}}{
\While{true}{
P(customers\_num\_sem)\;
P(mutex)\;
customer\_number $\leftarrow$ dequeue(customer\_queue)\;
V(mutex)\;
serve(customer\_number)\;
}
}
\end{algorithm}
实际实现的代码:
\lstinputlisting[language=c++, linerange=TELLER]{../banker.cpp}
对于客户线程,首先不断等待直到到达设定的进入时间,首先锁定客户队列,将自己加入,同时执行|V(customer_num_sem)|来向柜员线程提示有一个新的客户产生。伪代码如下:
\begin{algorithm}[htbp]
\caption{Customer Procedure}
\SetKwFunction{FMain}{Customer}
\SetKwProg{Fn}{Function}{:}{}
\Fn{\FMain{info}}{
sleep\_until(arrival\_time)\;
P(mutex)\;
enqueue(customer\_queue, info)\;
V(mutex)\;
V(customers\_num\_sem)\;
}
\end{algorithm}
实际实现的代码:
\lstinputlisting[language=c++, linerange=CUSTOMER]{../banker.cpp}
在实现了客户与柜员时,|main|函数只需要读取配置文件、创建所有的柜员和客户进程即可:
\lstinputlisting[language=c++, linerange=MAIN]{../banker.cpp}
\section{程序运行情况}
使用指导书中给出的测试数据和自己编写的测试数据都进行了测试。使用指导书中的输入:
\lstinputlisting{../test_data/1.txt}
得到的输出为
\lstinputlisting{../test_data/1_out.txt}
再使用自己编写的测试数据:
\lstinputlisting{../test_data/2.txt}
得到的输出为
\lstinputlisting{../test_data/2_out.txt}
可以看到正确实现了客户排队与柜员依次服务。
\section{思考题}
\begin{enumerate}
\item 柜员人数和顾客人数对结果分别有什么影响?
\begin{proof}[答]
当顾客人数很少时,几乎每时每刻都会有空闲的柜员,因此所有的客户刚到来就能获得服务,很少会有顾客等待,服务的总时间基本上只取决于$(\text{到达时间}+\text{服务时间})$最长的客户服务结束的时间;当柜员人数很少时,几乎时时刻刻所有的柜员都在工作,因此总时间将会取决于$\frac{\text{所有顾客所需要服务的总时间}}{\text{柜员的数量}}$
\end{proof}
\item 实现互斥的方法有哪些?各自有什么特点?效率如何?
\begin{proof}[答]
\begin{enumerate}
\item 将临界区设置禁止中断:简单有效,但是可靠性不高,且不适用于多处理器;
\item 锁变量:出现忙等,效率不高;
\item 严格轮转法:临界区外的进程也会阻塞其它进程,效率不高;
\item Peterson算法可以正常工作但是也会出现忙等效率比较低
\item 硬件实现:需要硬件支持,可以支持任意数目的进程,但是也可能出现忙等。
\item 信号量:效率比较高,但是信号量的控制不容易分析。
\end{enumerate}
\end{proof}
\end{enumerate}
\section{实验总结}
在本次实验中我在实践中学习了线程间的同步和互斥从实践中考虑问题进一步让我理解了P、V原语工作的核心思路与应用也在编程过程中学习了一些C++标准库的应用。
\appendix
\section{完整源代码}
\lstinputlisting[language=C++]{../banker.cpp}
\end{document}