操作系统课程设计:Linux系统管理实践与进程通信实现 - 图文
更新时间:2024-05-03 09:02:02 阅读量: 综合文库 文档下载
操作系统课程设计
——Linux系统管理实践与进程通信实现
二零一三年一月八号
一、设计内容
1、Linux系统的熟悉与常用操作命令的掌握。
2、Linux环境下进程通信的实现。(实现父母子女放水果吃水果的同步互斥问题,爸爸放苹果,女儿专等吃苹果,妈妈放橘子,儿子专等吃橘子,盘子即为缓冲区,大小为5。)
二、Linux环境介绍
1、Linux的由来与发展
Linux是一种可以在PC机上执行的类似UNIX的操作系统,是一个完全免费的操作系统。1991年,芬兰学生Linux Torvalds开发了这个操作系统的核心部分,因为是Linux改良的minix系统,故称之为Linux。 2、Linux的优点
(1)Linux具备UNIX系统的全部优点
Linux是一套PC版的UNIX系统,相对于Windows是一个十分稳定的系统,安全性好。
(2)良好的网络环境
Linux与UNIX一样,是以网络环境为基础的操作系统,具备完整的网络功能,提供在Internet或Intranet的邮件,FTP,www等各种服务。 (3)免费的资源
Linux免费的资源和公开的源代码方便了对操作系统的深入了解,给编程爱好者提供更大的发挥空间。 3、Linux的特点
1)全面的多任务,多用户和真正的32位操作系统 2)支持多种硬件,多种硬件平台 3)对应用程序使用的内存进行保护 4)按需取盘 5)共享内存页面
6)使用分页技术的虚拟内存 7)优秀的磁盘缓冲调度功能 8)动态链接共享库
9)支持伪终端设备 10)支持多个虚拟控制台 11)支持多种CPU
12)支持数字协处理器387的软件模拟 13)支持多种文件系统 14)支持POSIX的任务控制 15)软件移植性好
16)与其它UNIX系统的兼容性 17)强大的网络功能
三、常用命令介绍
1、目录操作
和DOS相似,Linux采用树型目录管理结构,由根目录(/)开始一层层将子目录建下去,各子目录以 / 隔开。用户login后,工作目录的位置称为 home directory,由系统管理员设定。‘~’符号代表自己的home directory,例如 ~/myfile 是指自己home目录下myfile这个文件。
Linux的通配符有三种:’*’和’?’用法与DOS相同,‘-‘代表区间内的任一字符,如test[0-5]即代表test0,test1,……,test5的集合。 (1)显示目录文件 ls
执行格式: ls [-atFlgR] [name] (name可为文件或目录名称) 例: ls 显示出当前目录下的文件
ls -a 显示出包含隐藏文件的所有文件 ls -t 按照文件最后修改时间显示文件 ls -F 显示出当前目录下的文件及其类型
ls -l 显示目录下所有文件的许可权、拥有者、文件大小、修
改时间及名称
ls -lg 同上
ls -R 显示出该目录及其子目录下的文件
注:ls与其它命令搭配使用可以生出很多技巧(最简单的如\,更多用法请输入ls --help查看,其它命令的更多用法请输入 命令名 --help
查看。
(2)建新目录 mkdir
执行格式: mkdir directory-name
例: mkdir dir1 (新建一名为dir1的目录) (3)删除目录 rmdir
执行格式: rmdir directory-name 或 rm directory-name 例:rmdir dir1 删除目录dir1,但它必须是空目录,否则无法删除 rm -r dir1 删除目录dir1及其下所有文件及子目录 rm -rf dir1 不管是否空目录,统统删除,而且不给出提示,使用
时要小心
(4)改变工作目录位置 cd
执行格式: cd [name]
例: cd 改变目录位置至用户login时的working directory cd dir1 改变目录位置,至dir1目录
cd ~user 改变目录位置,至用户的working directory cd 改变目录位置,至当前目录的上层目录 cd /user 改变目录位置,至上一级目录下的user目录 cd /dir-name1/dir-name2 改变目录位置,至绝对路径(Full path) cd 回到进入当前目录前的上一个目录 (5)显示当前所在目录 pwd
执行格式: pwd (6)查看目录大小du
执行格式: du [-s] directory
例:du dir1 显示目录dir1及其子目录容量(以kb为单位) du -s dir1 显示目录dir1的总容量 (7)显示环境变量
echo $HOME 显示家目录
echo $PATH 显示可执行文件搜索路径
env 显示所有环境变量(可能很多,最好用\PATH\等)
(8)修改环境变量,在bash下用export,如: export PATH=$PATH:/usr/local/bin
想知道export的具体用法,可以用shell的help命令:help export 2、文件操作
(1)查看文件(可以是二进制的)内容 cat
执行格式:cat filename或more filename 或cat filename|more 例: cat file1 以连续显示方式,查看文件file1的内容
more file1
或 cat file1|more 以分页方式查看文件的内容
(2)删除文件 rm
执行格式: rm filename 例: rm file?
rm f*
(3)复制文件 cp
执行格式: cp [-r] source destination
例: cp file1 file2 将file1复制成file2 cp file1 dir1 将file1复制到目录dir1 cp /tmp/file1 将file1复制到当前目录
cp /tmp/file1 file2 将file1 复制到当前目录名为file2
cp –r dir1 dir2 (recursive copy)复制整个目录。
(4)移动或更改文件、目录名称 mv
执行格式: mv source destination
例: mv file1 file2 将文件file1,更名为file2 mv file1 dir1 将文件file1,移到目录dir1下
mv dir1 dir2
(5)比较文件(可以是二进制的)或目录的内容 diff
执行格式: diff [-r] name1 name2 (name1、name2同为文件或目录) 例: diff file1 file2 比较file1与file2的不同处
diff -r dir1 dir2 比较dir1与dir2的不同处
(6)文件中字符串的查找 grep
执行格式: grep string file
例: grep abc file1 查找并列出串abc所在的整行文字 (7)文件或命令的路径寻找
执行格式一:whereis command 显示命令的路径
执行格式二:which command 显示路径及使用者所定义的别名 执行格式三:whatis command 显示命令的功能摘要
执行格式四:find search -path -name filename -print搜寻指定路径下某文件的路径
执行格式五:locate filename
根据系统预先生成的文件/目录数据库(/var/lib/slocate/slocate.db)查找匹配的文件/目录,查找速度很快,如果有刚进行的文件改变而系统未到执行定时更新数据库的时间,可以打入updatedb命令手动更新。 (8)建立文件或目录的链接 ln
例: ln source target1 建立source文件(已存在)的硬链接,命名为target1
ln -s source target2 建立source文件的符号链接,命名为target2
以下是几个常用命令操作的截图:
四、设计思想
当计算机中两个或多个进程在执行时需要使用公用缓冲区,并且对该缓冲区采取了互斥措施。这时如果并发执行这些进程就会造成CPU的极大浪费,这是操作系统设计要求不允许的。而这种现象在操作系统和用户进程中大量存在。因此为了解决这一问题,提出了同步的概念,即把异步环境下的一组并发进程,因直接制约而互相发送消息、互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。
在本次设计中,爸爸与妈妈、儿子与女儿的进程操作是互斥的,但是爸爸与女儿、妈妈与儿子进程之间的操作是同步的。因此要利用进程同步的方法来实现这几者之间的操作,当然其中也包含着互斥进程,因为盘子每次只能放入或取出一个水果。
程序设计中有如下四个进程:father(),mother(),daughter(),son()。
五、数据结构
1、信号量semid_mutex作为进程的公有信号量,其初始值为1,可以实现进程间的互斥,同时可以表示当前状态下盘子里可以放几个水果,实现进程间的同步。 2、信号量semid_full1为进程father()与daughter()的私有信号量,初值为0,表示当前盘子里苹果的数目。
3、信号量semid_full2为进程mother()与son()的私有信号量,初值为0,表示当前盘子里橘子的数目。
六、设计流程
爸爸放苹果流程图:
father操作 semid_mutex<=0 (P(semid_mutex)) 是 否 阻塞father进程 放苹果 唤醒daughter进程 V(semid_full1)
妈妈放橘子流程图:
mother操作 semid_mutex<=0 女儿吃苹果流程图:儿子吃橘子流程图:(P(semid_mutex)) 是 否 阻塞mother进程 放橘子 唤醒son进程 V(semid_full2) daughter操作 semid_full1<=0 (P(semid_full1)) 是 否 阻塞daughter进程 吃苹果 离开临界区 唤醒father进程 V(semid_mutex)
son操作 semid_full2<=0 (P(semid_full2)) 是 否 阻塞son进程 吃橘子 离开临界区 唤醒mother进程 V(semid_mutex)
七、源代码
#include
#define SHMKEY 9090 /*共享存储区的键*/ #define SEMKEY_EMPTY 9091 #define SEMKEY_MUTEX 9092 #define SEMKEY_FULL1 9093
#define SEMKEY_FULL2 9094 /*信号量数组的键*//*注意:上面的键在系统中必须唯一*/ #define BUFF_LEN 5/*缓冲区可以存放10个产品*/
#define PRODUCT_LEN 1 /*每个产品是一个字符串:<=32字符*/
void set_sembuf_struct(struct sembuf *sem,int semnum, int semop,int semflg)
{
/* 设置信号量结构 */ sem->sem_num=semnum; sem->sem_op=semop; sem->sem_flg=semflg; }
int begin() {
char *addr, end; int shmid;
int semid_empty, semid_full1,semid_full2, semid_mutex; struct sembuf sem_tmp;
/*开辟共享存储区*/
if ((shmid = shmget(SHMKEY, BUFF_LEN * PRODUCT_LEN+3, 0777|IPC_CREAT|IPC_EXCL)) == -1) {
if (errno == EEXIST) {
printf(\
printf(\ scanf(\
if(end == 'y' || end == 'Y') {
/* 共享存储区、信号量并不随程序的结束而被删除,如果我们没删除的话, 可以用ipcs命令查看,用ipcrm删除 */
/*释放缓冲区*/
shmid = shmget(SHMKEY, BUFF_LEN * PRODUCT_LEN+3, 0777); if (shmctl(shmid,IPC_RMID,0) < 0) perror(\
/*同时释放信号量*/
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); semctl(semid_mutex,0,IPC_RMID); semctl(semid_empty,0,IPC_RMID); semctl(semid_full1,0,IPC_RMID); semctl(semid_full2,0,IPC_RMID); } } else
printf(\ return -1; }
addr = (char*)shmat(shmid, 0, 0);/*连接缓冲区*/
memset(addr, 0, BUFF_LEN * PRODUCT_LEN+3); //初始化存储区 为0 shmdt(addr); /*离开缓冲区*/
/*创建3个信号量:1个用于对缓冲区互斥,2个用于生产者、消费者同步*/ if((semid_mutex = semget(SEMKEY_MUTEX,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_empty= semget(SEMKEY_EMPTY,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_full1 = semget(SEMKEY_FULL1,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
if((semid_full2= semget(SEMKEY_FULL2,1, 0777|IPC_CREAT|IPC_EXCL))==-1) {
if (errno == EEXIST)
printf(\ else
printf(\ return -1; }
/*给信号量赋初值*/
set_sembuf_struct(&sem_tmp, 0, BUFF_LEN, 0);/*BUFF_LEN*/ semop(semid_empty, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_full1, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 0, 0);/*0*/ semop(semid_full2, &sem_tmp,1);
set_sembuf_struct(&sem_tmp, 0, 1, 0);/*1*/ semop(semid_mutex, &sem_tmp,1);
return 0; }
/*下面的P,V是对系统调用的简单封装*/ int P(int semid) {
struct sembuf p_buf; p_buf.sem_num = 0; p_buf.sem_op = -1; p_buf.sem_flg = 0;
if(semop(semid, &p_buf, 1)==-1)/*semop参见课件ppt*/ {
perror (\ exit (1); } else
return 0; }
int V(int semid) {
struct sembuf v_buf;/*struct 参见课件ppt*/ v_buf.sem_num = 0; v_buf.sem_op = 1; v_buf.sem_flg = 0;
if(semop(semid, &v_buf, 1)==-1) { perror (\ exit (1); } else
return 0; }
int father()
{
int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2,rc3;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777);
rc1=semctl(semid_empty,0,GETVAL); rc2=semctl(semid_mutex,0,GETVAL); if(rc1==0) {
return 1; //不能放 則等待 }
if(rc2==0 ) {
return 1; }
P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ V(semid_mutex); V(semid_full1);
rc3=semctl(semid_full1,0,GETVAL);
printf(\ return 0; }
int mother()
{ int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2,rc3;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); rc1=semctl(semid_empty,0,GETVAL); rc2=semctl(semid_mutex,0,GETVAL);
if(rc1==0) {
return 1; //不能放 則等待
}
else if(rc2==0) {
return 1; }
P(semid_empty);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ V(semid_mutex); V(semid_full2);
rc3=semctl(semid_full2,0,GETVAL); printf(\ return 0; }
int son() {
int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); rc2=semctl(semid_full1,0,GETVAL); rc1=semctl(semid_full2,0,GETVAL); if(rc1==0) {
return 1; //不能放 則等待 }
P(semid_full2);/*对私有信号量作P操作*/ P(semid_mutex);
printf(\ printf(\ oranges to get \\n\ printf(\ V(semid_empty); V(semid_mutex); return 0; }
int daughter() {
int semid_empty, semid_full1,semid_full2, semid_mutex;/*信号量集合id*/ int rc1,rc2,rc3;
semid_mutex = semget(SEMKEY_MUTEX,1, 0777);/*获取全局信号量id*/ semid_empty = semget(SEMKEY_EMPTY,1, 0777); semid_full1 = semget(SEMKEY_FULL1,1, 0777); semid_full2 = semget(SEMKEY_FULL2,1, 0777); rc2=semctl(semid_full1,0,GETVAL); rc1=semctl(semid_full2,0,GETVAL); if(rc2==0) {
return 1; //不能放 則等待 }
P(semid_full1); P(semid_mutex);
printf(\ printf(\ apples to get \\n\ printf(\ APPLE\\n\ V(semid_empty); V(semid_mutex); return 0; }
int main() {
int pid; int i = 0, x; begin(); pid = fork(); if(fork()==0) { father(); } if(fork()==0) { mother(); } if(fork()==0) { daughter(); } if(fork()==0) { son();
}
return 0; }
八、调试与运行
首先,利用g++ ks.cpp编译一次,若有错误,则根据错误提示对程序进行修改。其次,编译通过后执行./a.out,若原先已有共享缓冲区,则删除原先缓冲区,再创建新的共享缓冲区.,然后再次执行./a.out,观察系统进程调度。
运行结果如下:
九、设计总结
在设计这个题目之前,由于对进程同步的实现方法不是很了解,对于怎样具
体实现进程同步有很大的疑问,所以在网上进行了查找,但几经搜索都没有找到合适的材料。就是在这种虽然有一定基础,但并不能完全依靠的前提下,自己通过查找相关的书籍,了解本次设计中涉及到的数据结构后,成功实现了进程同步的功能。从对进程同步只是一个概念上的认识,到最终将它的功能实现这一过程,我感到非常满意与欣慰,因为这些都是通过自己的努力一步一步实现的。
同时,本次课程设计也存在着不足之处。虽然熟悉和了解了程序中各数据结构的定义和创建,但是在一些细节问题上还没有一个很明确的认识,只是机械的合法的使用它。当然,在以后的课程设计中,我会更加追求完善,将不清晰的地方都弄明白。
正在阅读:
操作系统课程设计:Linux系统管理实践与进程通信实现 - 图文05-03
报关报检题库09-27
人力资源二级论文-绩效(三篇汇总)07-01
说话检讨书1000字02-12
湖南城市学院院系专业03-16
齿轮传动作业03-14
房地产专业术语11-09
蔡林森:此身再向学校行读后感04-11
税收筹划 课后习题答案01-08
廉政建设工作制度06-09
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 进程
- 操作系统
- 实践
- 课程
- 通信
- 实现
- 图文
- 设计
- 系统
- Linux
- 管理