MIT6.S081操作系统实验lab1

sleep实验

实验目标

sleep 10 停止10s

知识点

atoi将字符串转换为int

通关代码

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{

  if (argc ==1)
  {
      fprintf(2,"error\n");
  }
    int t = atoi(argv[1]);
    sleep(t);

  exit(0);
}

pingpong实验

实验目标

实现父子进程的通信

知识点

1.getpid可以获取当前进程的id
2.pipe(p[2])会将两个文件描述符保存到p[2]中,
一个管道可被写入多次,内容不会被覆盖,可分多次读出。管道是全双工的。

通关代码

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
char buf[512];

int
main(int argc, char *argv[])
{
    int p[2];
    int p2[2];

    pipe(p);

    pipe(p2);

    int pid = fork();
    if(pid==0) {
        close(p[1]);
        close(p2[0]);
        read(p[0],buf,2);//接受pid
        fprintf(1,"%s",buf);
        close(p[0]);

        fprintf(1,"%d: received ping\n",getpid());//打印接收到的pid
        write(p2[1],"s",1);
        close(p2[1]);
    } else {
        close(p2[0]);
        close(p[0]);
        write(p[1],"a",1);
                write(p[1],"b",1);

         close(p[1]);
        
        pid = wait(0);
        read(p2[0],buf,1);
        fprintf(1,"%d: received pong\n",getpid());//打印接收到的pid
        close(p2[0]);

    }
    exit(0);
}

primes实验

实验目标

使用素数筛法找出2~35中的素数。

知识点

1.父进程写数字进管道

 write(fd[WRITEEND],&numbers[i],sizeof(numbers[i]));

注意write的第二个参数是传入地址,第三个参数是传入该参数的字节数
2.子进程从管道读
while(read(fd[READEND],&temp,sizeof(temp))!=0)
读到的第一个数为素数,后面读到的数逐一除以该素数,若不整除则更新到number数组中。
3. 使用while循环控制子进程的创建,index=0时,只剩下最后一个元素,停止创建子进程。
4. 注意:fork之后,子进程也会有相同的管道和文件描述符,需要关掉用完的管道,exec不会覆盖文件描述符。

通关代码

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
char buf[512];

#define READEND 0
#define WRITEEND 1
int
main(int argc, char *argv[])
{
    int numbers[36];

    int index = 0;
    int fd[2];
    for(int i = 2;i<=35;i++)
    {
        numbers[index++]=i;
    }
    while(index>0)
    {
        pipe(fd);
        int pid = fork();

        if(pid>0)
        {
            close(fd[READEND]);
            for(int i=0;i<index;i++)
            {
                write(fd[WRITEEND],&numbers[i],sizeof(numbers[i]));

            }
            close(fd[WRITEEND]);
            wait(0);
            exit(0);
        }
        else if(pid==0)
        {
            close(fd[WRITEEND]);
            index=-1;
            int temp,prime=0;
            while(read(fd[READEND],&temp,sizeof(temp))!=0)
            {
                if(index<0)
                {
                    prime=temp;
                    index++;
                }
                else
                {
                    if(temp%prime!=0)numbers[index++]=temp;

                }

            }
            printf("prime %d\n", prime);

            close(fd[READEND]);
        }
    }
    exit(0);
}

find实验

实验目标

find . b
寻找该目录下所有叫b的文件并打印出来

知识点

1.stat是文件信息的结构体
在这里插入图片描述
可以根据type区分是目录还是具体文件(linux中目录也是文件)
2.fstat(fd, &st)可以将fd文件描述符(int类型)指向的文件的stat结构体信息赋值到st中。
3.

// Directory is a file containing a sequence of dirent structures.
#define DIRSIZ 14

struct dirent {
  ushort inum;
  char name[DIRSIZ];
}; 
fd为目录的文件描述符
可通过以下代码读取该目录下的文件
struct dirent de;
 while(read(fd, &de, sizeof(de)) == sizeof(de))

可通过以下代码筛选该目录下的文件
if(de.inum == 0 || 
strcmp(de.name, ".")==0 || 
strcmp(de.name, "..")==0)

4.stat(path, &st) ,其中path为char*,表示某文件的路径,st为stat结构体.将该文件的stat结构体信息赋值到st中。
5.fmtname(./a.txt)将path后面的文件名a.txt输出
6. memmove(p, de.name, DIRSIZ);
将de.name所指向地址的前DIRSIZ个字节拷贝到p所指向的地址中。
7.主要char*作为字符串时,末尾要有0.

通关代码

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

char*
fmtname(char *path)
{
  static char buf[DIRSIZ+1];
  char *p;

  // Find first character after last slash.
  for(p=path+strlen(path); p >= path && *p != '/'; p--)
    ;
  p++;

  // Return blank-padded name.
  if(strlen(p) >= DIRSIZ)
    return p;
  memmove(buf, p, strlen(p));
  buf[strlen(p)] = 0;
  return buf;
}

void
find(char *path,char *fileName)
{
  char buf[512], *p;
  int fd;
  struct dirent de;
  struct stat st;

  if((fd = open(path, 0)) < 0){
    fprintf(2, "ls: cannot open %s\n", path);
    return;
  }

  if(fstat(fd, &st) < 0){
    fprintf(2, "ls: cannot stat %s\n", path);
    close(fd);
    return;
  }

  switch(st.type){
  case T_FILE:
      //printf("filename:%s\n",fmtname(path));
      //printf("filename:%s\n",fileName);
      //printf("cmp:%d\n",strcmp(fmtname(path),fileName));
      if(strcmp(fmtname(path),fileName) == 0)
        printf("%s\n",path);
       break;

  case T_DIR:
    if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
      printf("ls: path too long\n");
      break;
    }
    strcpy(buf, path);
    p = buf+strlen(buf);
    *p++ = '/';
    while(read(fd, &de, sizeof(de)) == sizeof(de)){
        if(de.inum == 0 || strcmp(de.name, ".")==0 || strcmp(de.name, "..")==0)
          continue;
      memmove(p, de.name, DIRSIZ);
      p[DIRSIZ] = 0;
      if(stat(buf, &st) < 0){
        printf("ls: cannot stat %s\n", buf);
        continue;
      }
      find(buf,fileName);
      //printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
    }
    break;
  }
  close(fd);
}

int
main(int argc, char *argv[])
{

    find(argv[1],argv[2]);
  exit(0);
  return 0;
}

xargs实验

基础知识

  1. shell中的 ‘|‘ 是将标准输出转换为标准输入
  2. linux中的xargs命令是将标准输入转换为shell命令行参数(http://www.ruanyifeng.com/blog/2019/08/xargs-tutorial.html)

实验目标

实现xargs命令。

知识点

  1. char *arg = (char *)malloc(sizeof(line));
    

申请char的内存
2. exec(filename,params),其中param的第一个参数为命令名称,最后一个参数是0
在这里插入图片描述

  1. 一个字符一个字符的读取,遇到换行或空格则为一个word.
  2. 命令行一行最长4095bytes
  3. read(0,line,1024)返回的是读取到的字节长度
  4. free(arg)会把内存空间的内容也删掉。

通关代码

#include "kernel/types.h"
#include "kernel/param.h"
#include "user/user.h"

int main(int argc,char *argv[])
{
    char line[1024];
    char* params[MAXARG];
    int index = 0;
    for(int i=1;i<argc;i++) params[index++]=argv[i];
    int n = 0;
    char *cmd = argv[1];
    while((n=read(0,line,1024))>0)
    {
        if(fork()==0)
        {
            char *arg = (char *)malloc(sizeof(line));
            int arg_index = 0;
             for(int i=0;i<n;i++)
             {
                 if(line[i]==' '||line[i]=='\n')
                 {
                     arg[arg_index]=0;
                     arg_index = 0;
                     params[index++]=arg;
                     //free(arg);
                     arg = (char *)malloc(sizeof(line));
                 }
                 else
                 {
                     arg[arg_index++]=line[i];
                 }

             }
             params[index] = 0;
             exec(cmd,params);   
        }
        else
        {
            wait(0);
        }
    }
    return 0;
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值