西安郵電大學
操作系统设计报告
题 目:进程、线程、互斥锁
院系名称: 计算机学院
班 级: 1104
学生姓名: 赵大伟
学号(8位):04113124
指导教师: 舒新峰
设计起止时间:2013.11.10—2013.11.20
一. 设计目的
1) 通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间
等方面的特点,掌握在POSIX 规范中fork和kill系统调用的功能和使用。
2) 通过观察、分析实验现象,深入理解线程及线程在调度执行和内存空间
等方面的特点,并掌握线程与进程的区别。掌握POSIX 规范中
pthread_create() 函数的功能和使用方法。
3) 通过观察、分析实验现象,深入理解理解互斥锁的原理及特点掌握在
POSIX 规范中的互斥函数的功能及使用方法。
二. 设计内容
1)创建一个进程,父子进程 相互交替执行,输出子进程号和进程ID
2)创建三个线程,输出三个线程运行的次数和当前主线程运行次数以及三个线程次数和。
3)使用POSIX 规范中的互斥函数,实现加锁解锁
4)信号量机制的方法,实现进程的加锁解锁,且不产生死锁
三. 概要设计
1)生成一个进程,通过switch()判断,来确定生成的进程是子进程还是父进程,还是错误的;子进程号定义为全局变量;利用kill()杀死进程,退出程序。
2)利用循环创建三个线程,do while循环,每运行一次:输出三个线程运行的次数,当输入q时候,退出程序。
3)创建一个线程,在循环中进行申请资源,释放资源,加锁,以及解锁的操作,熟悉互斥锁的工作方式。
四.详细设计
1)进程交替进行
当程序执行到for(i = 0; i < child_proc_number; i++)循环后,调用fork()函数创建第一个子进程,然后父进程与该子进程交替执行,当子进程抢到cpu时继续往下执行case 0:语句中的do_something();语句,执行死循环for(;;)输出该进程的相关内容,并sleep,给其他进程抢占cpu的机会。这样就会使得进程交替的执行。
2)kill命令杀死进程
while ((ch = getchar()) != 'q') {
if (isdigit(ch)) {
i=ch-'0';kill(pid[i],SIGTERM);
}
}
for(i=0;i<10;i++){
kill(pid[i],SIGTERM);
}
return;
}
3)进程运行次数
do { unsigned long long sum = 0;
for (i=0; i<MAX_THREAD; i++) {
sum += counter[i];
printf("%llu\n ", counter[i]);
}
printf("%llu/%llu\n", main_counter, sum);
} while ((ch = getchar()) != 'q');
4)进程加锁,解锁
a、for(i = 0; i < LOOP_TIMES; i++)
{
pthread_mutex_lock(&mutex1);
pthread_mutex_lock(&mutex2);
critical_section(1,i);
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
}
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
b、for (i = 0; i < LOOP_TIMES; ++i) {
sem_wait(&S1);
sem_wait(&S2);
critical_section(1, i);
sem_post(&S1);
sem_post(&S2);
}
sem_destroy(&S1);
sem_destroy(&S2);
五.测试数据及运行结果
1) 进程.
各进程交替执行。无确定顺序
当输入要删除的进程编号时会调用一次kill,最后输入q结束时会调用一次kill。 输入q则显示“已终止”,整个程序执行结束。
2)线程
输出个各线程运行的次数,main_counter和sum的值
3)互斥锁
2.异常测试数据及运行结果 死锁:
六.调试情况,设计技巧及体会
1.改进方案
1)POSIX 规范中fork和kill都是有返回值的,为了程序更加严谨,应该在kill命令也使用接受返回值,如果返回值为-1,则退出。
2)程序退出时候使用了return(),但是书上介绍调用exit()结束的方式会比较好,这个需要以后注意
3)在有些地方,不应该使用死循环,虽然最后可以q退出,但是这样会导致CPU利用率很大
2.体会
在进程,线程,互斥锁编程序以后,自己对系统的运行以及管理有了初步的了解,也明白了进程和线程都是操作系统的程序运行的基本单元,明白了进程的创建,杀死,父子进程的关系,线程的并发执行,互斥锁的用法,但是自己还是知道自己在这些方面的使用还不是特别的熟练,自己还需要在以后的学习中,多多的写这方面的程序,以达到熟练掌握进程,线程,互斥锁的知识。
七、代码
1)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
#include<signal.h>
#define MAX_CHILD_NUMBER 10
#define SLEEP_INTERVAL 2
int proc_number=0;
void do_something();
main(int argc, char* argv[])
{ printf("proc_num=%p\n",&proc_number);
int child_proc_number = MAX_CHILD_NUMBER;
int i, ch;
pid_t child_pid;
pid_t pid[10]={0};
if (argc > 1)
{child_proc_number = atoi(argv[1]);
child_proc_number= (child_proc_number > 10) ? 10 :child_proc_number; }
for (i=0; i<child_proc_number; i++) {
child_pid=fork();
switch(child_pid)
{ case -1:perror("fork() error"); break;
case 0: proc_number=i; do_something(); break;
default: pid[i]=child_pid; break;
}
}
while ((ch = getchar()) != 'q') {
if (isdigit(ch)) { i=ch-'0';kill(pid[i],SIGTERM); }
}
for(i=0;i<10;i++){
kill(pid[i],SIGTERM); }
return;}
void do_something() {
int i;
printf("proc_num=%p",&proc_number);
for(i=0;i<10;i++) {
printf("This is process No.%d and its pid is %d\n", proc_number, getpid());
sleep(SLEEP_INTERVAL); } }
2)#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>
#define MAX_THREAD 3
unsigned long long main_counter, counter[MAX_THREAD];
void* thread_worker(void*);
int main(int argc, char* argv[])
{ int i, ch;
pthread_t pthread_id[MAX_THREAD] = {0};
for (i=0; i<MAX_THREAD; i++) {
pthread_create(&pthread_id[i], NULL, (void*)thread_worker, (void*)i); }
do { unsigned long long sum = 0; for (i=0; i<MAX_THREAD; i++) {
sum += counter[i];
printf("%llu\n ", counter[i]);
}
printf("%llu/%llu\n", main_counter, sum);
} while ((ch = getchar()) != 'q');
return 0;
}
void* thread_worker(void* p) {
int thread_num;
thread_num=(int)p;
for(;;) { counter[thread_num]++ ; main_counter++;
}
}
3)
代码1:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>
#define LOOP_TIMES 10000
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; void* thread_worker(void*);
void critical_section(int thread_num,int i);
int main(void)
{ int rtn,i;
pthread_t pthread_id = 0; rtn = pthread_create(&pthread_id,NULL,thread_worker,NULL); if(rtn != 0) { } for(i = 0; i < LOOP_TIMES; i++) { } pthread_mutex_destroy(&mutex1); pthread_mutex_lock(&mutex1); pthread_mutex_lock(&mutex2); critical_section(1,i); pthread_mutex_unlock(&mutex2); pthread_mutex_unlock(&mutex1); printf("pthread_create ERROR!\n"); return -1;
} pthread_mutex_destroy(&mutex2); return 0;
void* thread_worker(void* p)
{ int i;
for(i = 0; i < LOOP_TIMES; i++) { pthread_mutex_lock(&mutex1); pthread_mutex_lock(&mutex2); critical_section(2,i); pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
} }
void critical_section(int thread_num,int i) { printf("Thread%d:%d\n",thread_num,i);} 代码2:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <pthread.h>
#include <semaphore.h>
#define LOOP_TIMES 10000
sem_t S1, S2;
void *thread_worker(void*);
void critical_section(int thread_num, int i); int main() {
int rtn, i;
sem_init(&S1, 0, 1);
sem_init(&S2, 0, 1);
pthread_t pthread_id = 0;
rtn = pthread_create(&pthread_id, NULL, thread_worker, NULL); if (rtn != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
for (i = 0; i < LOOP_TIMES; ++i) {
sem_wait(&S1);
sem_wait(&S2);
critical_section(1, i);
sem_post(&S1);
sem_post(&S2);
}
sem_destroy(&S1);
sem_destroy(&S2);
return 0;
}
void *thread_worker(void *p) {
int i;
for (i = 0; i < LOOP_TIMES; ++i) {
sem_wait(&S1);
sem_wait(&S2);
critical_section(2, i);
sem_post(&S1);
sem_post(&S2);
}
return NULL;
}
void critical_section(int thread_num, int i) {
printf("Thread %d: %d\n", thread_num, i);
}
《网络操作系统》
课 程 设 计 报 告 书 题 目:
学 号:
学生姓名:
专 业:
指导教师: 银行家算法 121007339 周金英 网络工程 史军勇
20xx年 5 月30日
目 录
1 功能描述....................................................................................................................................... 3
1.1 银行家算法 ....................................................................................................................... 3
1.1.1 银行家算法实现功能 ........................................................................................... 3
2 系统设计....................................................................................................................................... 4
2.1 银行家算法流程图...........................................................................................................4
2.1.1 安全性检查流程图..........................................................................................................5
3 系统实现....................................................................................................................................... 5
4 系统测试与分析 ......................................................................................................................... 10
教师评分表..................................................................................................................................... 12
1 功能描述
系统中设置若干数据结构,避免死锁。
1.1 银行家算法
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则推迟分配。
1.1.1 银行家算法
进程i发出请求资源申请
(1)如果Request [j]<=need[i,j],转向步骤(2),否则认出错,所需资源数已经超过最大值。 (2)如果Request i[j]<=available[i,j],转向步骤(3),否则表示无足够资源,进程i需等待。
(3)若以上两个条件都满足,则系统试探着将资源分配给申请的进程,并修改下面数据结构中的数值:
Available[i,j]= Available[i,j]- Request [j];
Allocation[i][j]= Allocation[i][j]+ Request [j];
need[i][j]= need[i][j]- Request [j];
(4)试分配后,执行安全性检查,调用check函数检查此次资源分配后系统是否处于安全状态。否则本次试探分配作废,恢复原来的资源分配状态,该进程等待。
2 系统设计
图1
安全性算法流程图
3 系统实现
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define bool int
#define TRUE 1
#define FALSE 0
#define m 50
int no1; //进程数
int no2; //资源数
int r;
int allocation[m][m],need[m][m],available[m],max[m][m]; char name1[m],name2[m]; //定义全局变量
void main()
{
void check(); void print(); int i,j,p=0,q=0; char c; int request[m],allocation1[m][m],need1[m][m],available1[m]; printf("请输入进程总数:\n"); scanf("%d",&no1); printf("请输入资源种类数:\n"); scanf("%d",&no2); printf("请输入Max矩阵:\n"); for(i=0;i<no1;i++) scanf("%d",&max[i][j]); //输入已知进程最大资源需求量 for(j=0;j<no2;j++) printf("请输入Allocation矩阵:\n"); for(i=0;i<no1;i++) for(j=0;j<no2;j++) scanf("%d",&allocation[i][j]); //输入已知的进程已分配的资源数 for(i=0;i<no1;i++) for(j=0;j<no2;j++) need[i][j]=max[i][j]-allocation[i][j]; //根据输入的两个数组计算出need矩阵的值 printf("请输入Available矩阵\n"); for(i=0;i<no2;i++) scanf("%d",&available[i]); //输入已知的可用资源数 print(); //输出已知条件 check(); //检测T0时刻已知条件的安全状态 if(r==1) //如果安全则执行以下代码 { do{ q=0; p=0; printf("\n请输入请求资源的进程号(0~4):\n"); for(j=0;j<=10;j++) { scanf("%d",&i); if(i>=no1) { printf("输入错误,请重新输入:\n"); continue; } else break; } printf("\n请输入该进程所请求的资源数request[j]:\n"); for(j=0;j<no2;j++)
canf("%d",&request[j]);
for(j=0;j<no2;j++)
if(request[j]>need[i][j]) p=1;
if(p)
printf("请求资源超过该进程资源需求量,请求失败!\n");
else
{
for(j=0;j<no2;j++)
if(request[j]>available[j]) q=1; //判断请求是否超过可用资源数 if(q)
printf("没有做够的资源分配,请求失败!\n");
else //请求满足条件
{
for(j=0;j<no2;j++)
{
available1[j]=available[j];
allocation1[i][j]=allocation[i][j];
need1[i][j]=need[i][j];
available[j]=available[j]-request[j]; allocation[i][j]+=request[j];
need[i][j]=need[i][j]-request[j]; print();
check(); //检测分配后的安全性
if(r=0) //如果分配后系统不安全
{
for(j=0;j<no2;j++)
{
available[j]=available1[j]; allocation[i][j]=allocation1[i][j]; need[i][j]=need1[i][j]; }
printf("返回分配前资源数\n"); print();
}
}
}
c=getchar();
}while(c=='y'||c=='Y');
}
}
void check() //安全算法函数
{
int k,f,v=0,i,j; }
int work[m],a[m]; bool finish[m]; r=1; for(i=0;i<no1;i++) do { for(i=0;i<no1;i++) { if(finish[i]==0) { } f=1; for(j=0;j<no2;j++) if(need[i][j]>work[j]) f=0; finish[m]=0; // 初始化进程均没得到足够资源数并完成 work[i]=available[i];//work[i]表示可提供进程继续运行的各类资源数 for(i=0;i<no2;i++) k=no1; if(f==1) finish[i]=1; { a[v++]=i; //记录安全序列号 for(j=0;j<no2-1;j++) work[j]=work[j]+allocation[i][j]; //释放该进程已分配的资源 } } k--; //每完成一个进程分配,未完成的进程数就减1 }while(k>0); f=1; for(i=0;i<no1;i++) //判断是否所有的进程都完成 { } if(f==0) //若有进程没完成,则为不安全状态 { } else printf("系统处在不安全状态!"); r=0; if(finish[i]==0) { } f=0; break;
} { } printf("\n系统当前为安全状态,安全序列为:\n"); for(i=0;i<no1;i++) printf("p%d ",a[i]); //输出安全序列
void print() //输出函数 {
} int i,j; printf("\n"); printf("*************此时刻资源分配情况*********************\n"); printf("进程名/号 | Max | Allocation | Need |\n"); for (i = 0; i < no1; i++) { } printf("\n"); printf("各类资源可利用的资源数为:"); for (j = 0; j < no2; j++) { } printf("\n"); printf(" %d",available[j]); printf(" p%d/%d ",i,i); for (j = 0; j < no2; j++) { { printf(" %d ",allocation[i][j]); } for (j = 0; j < no2; j++) { } printf("\n"); printf(" %d ",need[i][j]); printf("%d ",max[i][j]);} for (j = 0; j < no2; j++)
4 系统测试与分析
教师评分表
《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.…
西安郵電大學操作系统设计报告题目进程线程互斥锁院系名称计算机学院班级1104学生姓名赵大伟学号8位04113124指导教师舒新峰设…
操作系统课程论文院系班级姓名学号指导教师完成时间东莞理工学院摘要本文分析面向对象教学操作系统EOS的系统结构和代码构成通过源代码分…
操作系统课程设计实验报告姓名学号班级地点20xx年月日任务说明共完成四个任务任务一IO系统调用开销比较任务二实现一个简单的shel…
操作系统课程设计总结报告学期20xx20xx学年第2学期学院软件学院学号姓名20xx年7月3日本学期开设了操作系统课程主要学习了计…
《操作系统原理》实验报告院(部):管理工程学院专业:信息管理与信息系统实验项目:实验一二三五班级:信管102姓名:学号:目录引言.…
操作系统课程设计报告专业学号姓名提交日期操作系统课程设计报告设计目的1本实验的目的是通过一个简单多用户文件系统的设计加深理解文件系…
上海电力学院计算机操作系统原理课程设计报告题目名称编写程序模拟虚拟存储器管理姓名杜志豪学号20xx1798班级20xx053班同组…