一、操作系统实训一
在Linux中的超级终端测试递归和非递归两种方法求解斐波那契数列所用的时间
1、指令:
在超级中端中
- 创建文件:touch + 文件名 //注意文件名后缀为.c
- 进入编程模式:gedit +上一步创建的文件名 //这两步可以合成一步:vim/vi + 文件名详情
- 编译文件:gcc + 文件名
- 查看文件:ls
- 执行编译后的程序:./a.out
2. 超级终端中的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#define MILLION 1000000
int f1(int n){ /*递归求解*/
if(n==1||n==2){
return 1;
}
return f1(n-1) + f1(n-2);
}
int f2(int n){
int a=1;
int b=1;
int c=1;
while(n>2){
c=a+b;
a=b;
b=c;
n--;
}
return c;
}
static struct timeval time_start(){ /*记录程序起始时间*/
struct timeval tv;
gettimeofday(&tv, NULL);
return tv;
}
static long msdiff(struct timeval start){ /*直接计算出程序的运行时间*/
struct timeval tv;
gettimeofday(&tv, NULL);
return ((MILLION*(tv.tv_sec-start.tv_sec)+tv.tv_usec-start.tv_usec)/1000);
}
int main(int argc, char *argv[])
{
struct timeval startTime;
int result;
int n;
long runTime;
scanf("%d",&n);
startTime = time_start();
result=f2(n);
runTime=msdiff(startTime);
printf("Value is %d, Comsumed Time:%ld ms\n",result,runTime);
return EXIT_SUCCESS;
}
二、操作系统实训二
在Linux中的超级终端编写一个my_student_id.sh,并求输入参数的和
输入一串数字,然后进行求和
#方法1:
#!/bin/bash
function add(){
sum=0
echo "Please enter any number:"
read strs #读入一串数字
array=(${strs//\ / }) #字符串替换,然后赋值个array数组
for i in "${!array[@]}" #遍历array数组,其中${!array[@]表示array数组所有的下标
do
let sum+=array[i]
done
echo $sum
}
add
#方法2:
#!/bin/bash
function main(){
sum=0
for n in "$@"
do
let sum+=n
done
echo $sum
}
main $@ #注意传参数
#当然还可以直接用for循环来写
三、操作系统实训三
在Linux超级终端中编写一个C程序,使用fork()和lockf()两个函数使两个多个进程轮流输出
- 利用fork()函数创建两个子进程,使得三个进程轮流输出
//方法1:利用if,else使进程之间形成互斥,让多个进程形成互斥
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char *argv[]) {
int p1,p2,i;
p1=fork();
printf("p1=%d\n",p1);
//lockf(1,1,0);
if(!p1) {
for(i=0; i<3; i++) {
printf("son!\n",p1);
//printf("p1=%d\n",p1);
sleep(1);
}
//lockf(1,0,0);
} else {
p2=fork();
printf("p1=%d;p2=%d\n",p1,p2);
//lockf(1,1,0);
if(!p2) {
for(i=0; i<3; i++) {
printf("daughter!\n");
//printf("p1=%d;p2=%d\n",p1,p2);
sleep(1);
//lockf(1,0,0);
}
} else {
//lockf(1,1,0);
for(i=0; i<3; i++) {
printf("parent!\n");
sleep(1);
//printf("p1=%d;p2=%d\n",p1,p2);
}
//lockf(1,0,0);
}
}
return 0;
}
//方法2:利用return让多个进程轮流输出
#include<sys/stat.h>
#include<stdio.h>
#include<unistd.h>
pid_t fork(void);
int main() {
int p1,p2,p3,i;
p1=fork();
//printf("p1=%d\n",p1);测试进程
if(p1==0) {
lockf(1,1,0);
for(i=0; i<3; i++) {
printf("son!\n",p1);
// printf(" p1=%d\n",p1);
sleep(1);
}
lockf(1,0,0);
return 0;
}
p2=fork();
if(p2==0){
//printf("p1=%d;p2=%d\n",p1,p2);{
lockf(1,1,0);
for(i=0; i<3; i++) {
printf("daughter!\n");
//printf("p1=%d;p2=%d\n",p1,p2);
sleep(1);
}
lockf(1,0,0);
return 0;
}
p3=fork();
if(p3==0){
lockf(1,1,0);
for(i=0; i<3; i++) {
printf("parent!\n");
//printf(" p1=%d;p2=%d;p3=%d\n",p1,p2,p3);
sleep(1);
}
lockf(1,0,0);
return 0;
}
return 0;
}
四、操作系统实训四
理解Linux 系统中进程间的通信方式IPC
- 共享内存通信方式:
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<stdlib.h>
#include<sys/stat.h>
int main() {
int shmid=shmget(IPC_PRIVATE, 1024, IPC_CREAT|0600);
char *p_addr=NULL ;
char *c_addr=NULL ;
//创建共享内存
if(fork()>0) {
p_addr=shmat(shmid,0,0);
strncpy(p_addr , "Hello,122\n",1024);
shmdt(p_addr);
//释放映射
//等待子进程执行结束(确保消息被接收),status是整形变量wait(NULL);
wait(NULL);
shmctl(shmid, IPC_RMID, NULL);
//删除共享内存
} else {
c_addr= shmat(shmid,0,0);
printf("%s\n",c_addr);
//打印(输出)消息
shmdt(c_addr);
//释放映射
}
}
- 管道通信机制:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/shm.h>
#include<errno.h>
int main(){
int fd[2];
char recvBuf[1024],sendBuf[1024];
if(pipe(fd)<0){//创建管道
perror("pipe:");
}
if(fork()==0){//子进程从通道读取
close(fd[1]);
read(fd[0],recvBuf,1024);
printf("Hello,%s!(using a pipe)\n",recvBuf);
}else{//父进程向通道写入
close(fd[0]);
scanf("%s",sendBuf);
write(fd[1],sendBuf,1024);
}
}
五、操作系统实训五
银行家算法检测安全序列
#include <stdio.h>
#define PROCESS_AMOUNT 5 //进程数量
#define RESOURCE_AMOUNT 3 //资源数量
//记录各个进程执行完成的顺序
int Process[PROCESS_AMOUNT];
//判断是否安全,即寻找安全序列
int is_safe();
//系统提供的各类资源的最大量
int Resoure_Max[3]= {17,5,20};
//各个进程需要的最大资源数量
int Max[PROCESS_AMOUNT][RESOURCE_AMOUNT]= {
{5,5,9},
{5,3,6},
{4,0,11},
{4,2,5},
{4,2,4},
};
//以分配给每个进程的资源数量
int Allocation[PROCESS_AMOUNT][RESOURCE_AMOUNT]= {
{2,1,2},
{4,0,2},
{4,0,5},
{2,0,4},
{3,1,4},
};
//各个进程还需要的资源数量
int Need[PROCESS_AMOUNT][RESOURCE_AMOUNT];
//工作向量,表示系统可提供的资源数量
int Work[RESOURCE_AMOUNT];
//记录各个进程是否完成,0表示未完成,1表示完成
int Finish[PROCESS_AMOUNT]= {0};
//记录各个进程执行完成的顺序
int Process[PROCESS_AMOUNT];
int main(void) {
int i,j;
//初始化, you should deal with initialization
for(i=0; i<RESOURCE_AMOUNT; i++) {
Work[i]=Resoure_Max[i];
}
for(i=0; i<PROCESS_AMOUNT; i++) {
for(j=0; j<RESOURCE_AMOUNT; j++) {
Work[j]-=Allocation[i][j];
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
if(is_safe()) {
printf("找到这样的安全系列:\n");
for(i=0; i<PROCESS_AMOUNT; i++) {
printf("%-3d",Process[i]);
}
printf("\n");
} else {
printf("此时刻不安全!!\n");
}
return 0;
}
//判断是否安全,即寻找安全序列
int is_safe() {
int i,index,j;
for(i=0; i<PROCESS_AMOUNT; i++) {
/*找一个当前资源能够满足需求,且没有找过的进程*/
index=search_need();
if(index<0) {
return 0;
} else {
for(j=0; j<RESOURCE_AMOUNT; j++) {
Work[j]+=Allocation[index][j];
}
Finish[index]=1;
Process[i]=index;
}
}
return 1;
}
//在Need矩阵中查找是否所需的各个资源数量都小于Work数组的资源数量,成功返回下标,不成功返回-1
int search_need() {
int i,j,f=0;
for(i=0; i<PROCESS_AMOUNT; i++) {
if(Finish[i]==0) {
f=0;
for(j=0; j<RESOURCE_AMOUNT; j++) {
if(Work[j]<Need[i][j]) {
f=1;
break;
}
}
if(f==0) {
return i;
}
}
}
return -1;
}