指导教师:胡晓鹏
实验报告一
实验名称:Linux操作系统下的C语言编程
实验目的:1.认识Linux系统,熟悉Linux操作系统的基本操作;
2.了解vi命令的基本用法,能够使用vi命令对文件进行基础的操作与编辑;
3.能够在Linux环境下编写C语言程序,生成.out文件,并成功执行;
4.体会Linux环境下编程与Windows环境下编程的异同,加深对Linux操作系统的理解。
实验内容:熟悉Linux环境,编写简单C语言程序。
实验结果:
实验结论:在Linux操作系统下的编程环境不同于Windows,编译器进行命令编译。操作环境简洁,大多以键盘操作。
实验报告二
实验名称:基于进程与线程的并发
实验目的:
1.了解进程与线程工作原理,掌握并发机制,学会编写简单的并发程序。
2.充分理解并掌握基于进程与线程的并发。
实验内容:在Linux环境进行基于进程与线程编写实验程序。
试验核心代码:
int main()
{ pthread_t tid[N];
pid_t pid;
pid=fork();
if(pid<0)
{ printf("fail to fork\\n");
exit(1);
}
else if(pid==0)
{ printf("the child process:\\n");
}
else
{ sleep(10);
printf("the parent process:\\n");
}
void *res;
int err[3];
err[0]=pthread_create(&tid[0],NULL,fn1,NULL);
err[1]=pthread_create(&tid[1],NULL,fn2,NULL);
err[2]=pthread_create(&tid[2],NULL,fn3,NULL);
int i;
for(i=0;i { printf("cannot join the thread %d\\n",i); exit(1); } } return 0; } void *fn1(void *arg) { printf("the first thread is done\\n"); return (void *)1; } void *fn2(void *arg) { printf("the second thread is done\\n"); // sleep(1); return (void *)1; } void *fn3(void *arg) { printf("the third thread is done\\n"); // sleep(2); return (void *)1; } 实验结果: 实验结论:进程与线程之间的关系为线程离不开进程,线程在多任务系统的作用使计算机高校工作,同时下创建进程是应尽量避免进程的出现。掌握线程pthread_join()中的阻塞原理。 实验报告三 实验题目: 进程间的通信 实验目的:学习在linux环境进程间的信息传递和接收,理解进程间的信号通信,并能编写简单代码实现进程间的通信。 实验代码: #include #include #include #include #include static int alarm_fired=0; void ouch(int sig) { alarm_fired=1; } int main() { pid_t pid; pid=fork(); if(pid==-1) { printf("fork failed\\n"); exit(1); } else if(pid==0) { kill(getpid(),SIGALRM); exit(0); } signal(SIGALRM,ouch); alarm(5); pause(); if(alarm_fired==1) printf("receive a signal %d\\n",SIGALRM); exit(0); } 实验结果: 实验结论:进程能进行信息通信,如果进程间有必要,能够实现很好的进程异步处理。 实验报告四 实验题目: 进程间的通信-共享内存 实验目的:理解进程间共享内存机制,学会分析共享内存之间的通信方式并进行内存共享实践,编写简单程序实现内存简单共享。 实验代码: 核心代码: /**************************************************************/ //定义数据结构体 struct shared_use_st { int written_by_you; char some_text[TEXT_SZ]; }; /*写入*********************************************************/ /*创建共享内存*/ shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT); if(shmid==-1) { fprintf(stderr,"shmget failed\\n"); exit(EXIT_FAILURE); } /*映射共享内存*/ shared_memory=shmat(shmid,(void *)0,0); if(shared_memory==(void *)-1) { fprintf(stderr,"shmat failed\\n"); exit(EXIT_FAILURE); } printf("Memory attached at %X\\n",(int)shared_memory); /*让结构体指针指向这块共享内存*/ shared_stuff=(struct shared_use_st *)shared_memory; /*循环的向共享内存中写数据,直到写入的为“end”为止*/ while(running) { while(shared_stuff->written_by_you==1) { sleep(1);//等到读进程读完之后再写 printf("waiting for client...\\n"); } printf("ener some text:"); fgets(buffer,BUFSIZ,stdin); strncpy(shared_stuff->some_text,buffer,TEXT_SZ); shared_stuff->written_by_you=1; if(strncmp(buffer,"end",3)==0) { running=0; //结束循环 } } /*读取***********************************************************************/ /*创建共享内存*/ shmid=shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT); if(shmid==-1) { fprintf(stderr,"shmget failed\\n"); exit(EXIT_FAILURE); } /*映射共享内存*/ shared_memory=shmat(shmid,(void *)0,0); if(shared_memory==(void *)-1) { fprintf(stderr,"shmat failed\\n"); exit(EXIT_FAILURE); } printf("Memory attached at %X\\n",(int)shared_memory); /*让结构体指针指向这块共享内存*/ shared_stuff=(struct shared_use_st *)shared_memory; /*控制读写顺序*/ shared_stuff->written_by_you=0; /*循环的从共享内存中读数据,直到读到“end”为止*/ while(running) { if(shared_stuff->written_by_you) { printf("You wrote:%s",shared_stuff->some_text); sleep(1); //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写 shared_stuff->written_by_you=0; if(strncmp(shared_stuff->some_text,"end",3)==0) { running=0; //结束循环 } } } 实验结果: 实验结论:内存共享中应该含有安全防护机制,内存在共享的同时应该做到内存的保护,共享内存段是更应该做到安全高效共享。应当加强训练共享内存段申请原则,多多学习管道运输的实现。 实验报告五 实验题目:虚拟内存 实验目的:模拟替换算法技术,编程实现LRU和CLOCK算法,掌握替换算法技术,完全实现替换策略。 实验主要函数: void lru_p(int n,int m,int proc[]); void clock_p(int n,int m,int proc[]); 实验代码: #include #include #include using namespace std; void lru_p(int n,int m,int proc[]) { cout<<"------------------------------------------"< struct page { int time; int pro; }; struct page *p=(struct page*)malloc(n*sizeof(page)); int i = 0; int flag = 0; //记录是否满页 int exit; //初始化时间 for(int j=0;j p[j].time=0; } while(i exit=0; for(j = 0;j p[j].time++; if(p[j].pro == proc[i]) //处理相同如何情况下的相同进程 { exit=1; p[j].time=1; } } if(exit==0&&(flag p[flag].time=1; flag++; } else if(exit==0) //处理缺页 没有相同进程但缺页 { int key=0; int maxtime=p[0].time; for(j=1;j { maxtime=p[j].time; key=j; } p[key].pro=proc[i]; p[key].time=1; } //输出 for(j=0;j printf(" %d ",p[j].pro); } cout< } } void clock_p(int n,int m,int proc[]) { cout<<"------------------------------------------"< { int flag; int pro; }; struct page *p=(struct page*)malloc(m*sizeof(page)); //初始化队列 for(int k=0;k int i=0; int next; int j=0; //标记初始位置 int mart=0; while(i while(next) { for(k=0;k if(p[k].pro==proc[i]) { next=0; } } if(next) { if(!p[j].flag) { p[j].pro=proc[i]; p[j].flag=1; next=0; if(mart } else { p[j].flag=0; next=1; if(mart } j++; j=j%n; } } //输出 i++; for(k=0;k cout< } } void main() { int pages; cout <<"输入页面数:"; cin>>pages; cout<<"输入你的进程个数:"; int m; cin>>m; cout<<"输入你的进程ID:"; int *proc=new int[m]; for(int i=0;i lru_p(pages,m,proc); clock_p(pages,m,proc); } 实验结果: 实验结论: 替换策略是计算机高效工作,充分利用资源,而不同的替换算法都有自己的利弊,不同的场景应充分权衡利弊进行选择。 实验报告六 实验题目:进程调度和轮循 实验目的:理解掌握进程调度算法,使用程序实现算法,学会分析调度算法,以加深对进程的概念及进程调度算法的理解。 实验代码: 核心代码: ----------------------实现函数-------------------- //定义存放nums个进程PCB的链表的头结点; PCB* linkinit() //初始化链表的头结点; { PCB* head1; head1=(PCB *)malloc(sizeof(PCB)); head1->next=NULL; return head1; } //往链表中添加进程PCB节点; void linkadd(PCB* head) { PCB* r,* q=head; r=(PCB *)malloc(sizeof(PCB)); while(q->next)q=q->next; void inputdata(PCB* r); inputdata(r); r->next=q->next; q->next=r; } //向链表PCB节点内容中输入数据 void inputdata(PCB* r) { printf("进程名:");scanf("\\n%c",&r->name); printf("到达时间:");scanf("%d",& r->reach_time); printf("运行时间:");scanf("%d",& r->run_time); } //以“到达时间”的从大到小的顺序对链表进行排序 void seq(PCB* head) { PCB* h=head; while(h->next->next) { PCB* p=h->next,*q=h->next; while(q->next) { q=q->next; if(p->reach_time > q->reach_time) p=q; } PCB* r=h; while(r->next!=p) r=r->next; r->next=p->next; p->next=h->next; h->next=p; h=h->next; } } //求最大的到达时间 int mrtime(PCB* head) { PCB* p=head; while(p->next) p=p->next; int maxreachtime=p->reach_time; return maxreachtime; } //将各个进程运行时间的初始值赋给p->rt;在求"带权周转时间"的时候要用到 void runtort(PCB* head) { PCB* p=head; do { p=p->next; p->rt=p->run_time; }while(p->next); } void output(PCB* head,int nums) { PCB* t=head; int zzs_time=0;float dqzzs_time=0.00; while(t->next!=NULL) { t=t->next; printf("进程名:%c\\n",t->name); printf("\周转时间:%d\\n",t->zz_time); printf("\带权周转时间:%f\\n",t->dqzz_time); zzs_time=zzs_time+t->zz_time; dqzzs_time=dqzzs_time+t->dqzz_time; } printf("\\n平均周转时间:%f\\n",(float)zzs_time/nums); printf("平均带权周转时间:%f\\n",(float)dqzzs_time/nums); } --------------------------------主函数------------------------------- void main() { int nums; printf("请输入要运行的进程个数:"); scanf("%d",&nums); //nums代表要运行的进程的个数; PCB* head; head=linkinit(); for(int i=1;i<=nums;i++) linkadd(head); seq(head); //对PCB链表中的节点进行“运行时间”的排序(小-->大) int maxreachtime=mrtime(head); runtort(head); //将运行时间的初值赋给p->rt PCB* p=head->next; int t=0;//时钟,用于记录进程运行的时间 while(p->run_time!=0||p->next!=NULL) { if(p->run_time) { p->run_time--; printf("进程%c的剩余运行时间为:%d\\n",p->name,p->run_time); t++; if(p->run_time==0) { p->state='C'; p->zz_time=maxreachtime+1-p->reach_time+t; p->dqzz_time=(float)p->zz_time/p->rt; } PCB* q=p; if(p->next!=NULL) { p=p->next; //inserttoend(head); PCB* t=head; while(t->next!=NULL)t=t->next; PCB* r=head; while(r->next!=q)r=r->next; r->next=q->next; t->next=q; q->next=NULL; } } else p=p->next; } output(head,nums); } 实验结果: 实验结论:进程调度是多任务操作系统的重要最组成部分,进程调度的实现,是多任务操作正常工作的基本要求,理解和掌握进程调度和轮循,是学习操作的系统基本任务,模拟调度的实现,加深了对调度算法的理解,更是掌握了调度算法的应用。