操作系统课程设计报告 (8)

哈尔滨理工大学

课 程 设 计

(计算机操作系统)

题  目:         用户命令接口

  

班  级:   

姓  名:  

指导教师:      

系主任:     

20##年03月01日


目   录

1用户命令接口课程设计................................................................................................... 1

1.1 题目分析................................................................................................................... 1

1.2 数据结构................................................................................................................... 1

1.3 流程图....................................................................................................................... 1

1.4 实现技术................................................................................................................... 2

1.5 设计结论和心得....................................................................................................... 2

2 Linux代码分析................................................................................................................. 3

2.1 功能说明................................................................................................................... 3

2.2 接口说明................................................................................................................... 3

2.3 局部数据结构........................................................................................................... 3

2.4 流程图....................................................................................................................... 3

2.5 以实例说明运行过程............................................................................................... 4

第1章


1用户命令接口课程设计

1.1 题目分析

用户命令接口是为了用户直接或间接控制自己的作业,操作系统向用户提供了命令接口。命令接口是用户利用操作系统命令组织或控制作业的执行或管理计算机系统。命令是在命令输入界面上输入,由系统在后台执行,并将结果反映到前台界面或者特定的文件内。

1.2 数据结构

1、为Windows操作系统建立一个兼容Unix命令的命令接口;

     2、实现命令包括ls,cat,cp,mv,md,rd,cd,sort,more,print,命令的内容与详细格式请查阅uni命令手册;

     3、可以字符形式接收命令,执行命令,然后显示命令执行结果。

1.3 流程图

1.4 实现技术

为实现上述设计,采用C++语言,VS2008开发环境。具体采用的技术如下:

(1)void lsFunction(string *lsinput,int lscount)函数实现显示一个目录中的文件和子目录。如果失败返回显示“路径可能不存在!” 。

(2)void catFunction(string *catinput,int catcount)函数实现打开文件并显示内容。如果失败返回显示“无法打开文件!”。

(3)void cpFunction(string *cpinput,int cpcount)函数实现复制文件和目录树。如果成功返回显示“复制成功”,否则显示“文件或目录可能不存在!” 。

(4)void mvFunction(string *mvinput,int mvcount)函数实现将文件从一个目录移到另一个目录。如果成功返回显示“成功” ,否则显示“文件或目录可能不存在!” 。

(5)void mdFunction(string *mdinput,int mdcount)实现在指定的目录或文件下创建目录。

(6)void rdFunction(string *rdinput,int rdcount)函数实现删除空目录。如果成功返回显示“删除目录成功” ,否则显示“文件夹可能不存在或文件夹不为空!” 。

(7)void cdFunction(string *cdinput,int cdcount)函数实现显示当前目录的名称或将其更改。如果失败返回显示“路径可能不存在!” 。

#include "windows.h"

#include "fstream"

#include "string"

#include "iomanip"

#include "iostream"

using namespace std;

#define PRINTHEADHELP

void cathelpFunction()

{

    cout<<PRINTCATHELP<<endl;

};

    infile.close();

    return f;

}*/

void catFunction(string *catinput,int catcount)

{

    void printPath(void);

    if (1 == catcount)

    {

        cout<<"命令语法不正确!"<<endl;

        printPath();

    }

    if (2 == catcount)

    {

        ifstream infile(catinput[1].c_str(),ios::in);

        if (!infile)

        {

//------3、cp

void cphelpFunction()

{

    cout<<PRINTCPHELP<<endl;

}

void cpFunction(string *cpinput,int cpcount)

{

    //cpcount = 3 --> cp 源文件路径 目的文件路径

    //另外在copy的过程可以进行重命名操作,即cpinput[2].c_str()

    void printPath(void);

    if (1 == cpcount)

    {

        cout<<"命令语法不正确!"<<endl;

        printPath();

    }

    else

    {

        if (!CopyFile(cpinput[1].c_str(),cpinput[2].c_str(),1))

        {

            cout<<"文件或目录可能不存在t!"<<endl;

            printPath();

        }

        else

        {

            cout<<"复制文件成功!"<<endl;

            printPath();

        }

    }

}

1.5 设计结论和心得

操作系统的基本特征是并发与共享。系统允许多个进程并发执行,并且共享系统的软、硬件资源。为了最大限度的利用计算机系统的资源,除了更深的了解这个算法,而且对C语言进行了复习,而且其过程中有很多的知识点都不记得了,所以在此感谢在此过程中帮助过我的老师和同学。最后的感悟就是:只要你亲自动手,你就能学到知识。


2 Linux代码分析

2.1 功能说明

在操作系统中,有些进程存在着相互制约的关系,这些制约关系来源于并行进程的相互合作和资源共享。为了使合作进程和资源共享进程能协调一致的向前推进,必须使他们保持联系,一边相互了解。进程相互间需要交换一定数量的信息,以便协调一致共同完成指定的任务. 这种机制就叫做进程间通信,或IPC.在linux 中支持UNIX SYSTEM V 的三种通信机制: 消息队列, 信号量和共享内存. 现就消息队列这种机制进行分析.

2.2 接口说明

本程序的输入参数为:

1.          struct ipc_perm

{  

    key_t key;   // 整型, 0表示private, 非0表示public

ushort uid;   // 资源拥有者的有效标识

ushort gid;   // 资源拥有者所在组的有效标识

ushort cuid;   // 资源创建者的有效标识

ushort cgid;   // 资源创建者所在组的有效标识 

ushort mode;  //  访问模式

ushort  seq;  // 序列号, 计算标识符

          ];

        系统在创建消息队列的同时设定了访问权限, 并返回一个标识. 进程通信时必须先传递该标识, 待函数ipcperms()确认权限后才可以访问通信资源. 访问权限由ipc_perm 结构描述. 通过key可以得到引用标识, 从而访问通信资源. Key 为public , 则任何进程都可以通过key得到引用标识.

2.   struct msg

   {  

struct msg *msg_next;   //消息队列中的下一个

       long msg_type;         //消息的类型

       char *msg_spot;        //存放消息内容的地址

       time_t msg_time;       //消息发送的时间

       short msg_ts;          //消息的长度

   };        

msg 结构用来存放消息的有关信息.

3.   struct msqid_ds

struct ipc_perm msg_perm; 

   struct msg *msg_first;       //指向消息队列的第一条消息

   struct msg *msg_last;        //指向消息队列的最后一条消息

   time_t msg_stime;           // 最后发送时间

   time_t msg_rtime;           //最后接收时间

   time_t msg_ctime;           //最后修改时间

   struct wait_queue *wwait;    //写消息进程的等待队列

   struct wait_queue *rwait;    //读消息进程的等待队列

   ushort msg_cbytes;          //队列中消息的字节数

   ushort msg_qnum;           //队列中的消息数

   ushort msg_qbytes;          //队列中消息的最大字节数

   ushort msg_lspid;        // 最后一个发送消息的进程的标识号

   ushort msg_lrpid;        //最后一个接收消息的进程的标识号

};

   每一个msqid_ds 结构代表一个消息队列, 是进程读写的信息的存储空间。

            static struct msqid_ds *msgque[MSGMNI];

   定义了一个消息队列数组msgque, 数组的元素类型是指向msqid_ds 结构的指针。消息在队列中是按到来的顺序维护。进程读消息时,这些消息按FIFO从队列中移去。

4.  struct msgbuf

long  mtype;           //消息的类型

   char  mtext[1];         //消息的内容

};

   存放消息的信息。

5.   struct wait_queue

           { 

struct wait_queue *next;  //指针指向等待队列的下一个

       struct task_struct *task; 

       /*task_struct 存放的是进程控制块的信息*/

          };

    wait_queue代表各种各样的进程等待队列。

2.3 局部数据结构

1.       初始化模块:

void __init msg_init (void)

函数参数:无

函数返回类型:空

函数功能:对消息队列及各变量初始化

{

   int id;

     for (id = 0; id < MSGMNI; id++)

           msgque [id] = (struct msqid_ds *) IPC_UNUSED;

       

/* 给指向消息队列的指针分配空间,标志为IPC_UNUSED,定义见

       linux/ipc.h : #define IPC_UNUSED  ((void ) -1)*/

   msgbytes = msghdrs = msg_seq = max_msqid = used_queues = 0;

   msg_lock = NULL;

   return;

}

2.            发送消息模块:

static int real_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg)

函数参数:

   msqid: 整型, 消息的序列号;

   msgp: 指向msgbuf结构的指针;

   msgsz: 消息的大小;

   msgflg: 消息的标志符。

函数返回类型:若消息正确的放入消息队列,则返回0,否则返回各错误信息。

函数功能:将msgp所指向的消息缓冲区的内容放入消息队列中,且将标志号设为msqid。其他调用可通过msqid访问消息队列。

3.  接收消息模块;

static int real_msgrcv (int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg)

函数参数:

  msqid: 整型, 消息的序列号;

  msgp: 指向msgbuf结构的指针;

  msgsz: 消息的大小;

  msgtyp: 消息的类型;

  msgflg: 消息的标志符。

函数返回类型:若接收正确,返回接收到的消息字节数。否则,返回错误信息。

函数功能:从消息队列中接收标示号为msqid,内容为msgp所指向的信息。

 

4.  创建或获得消息的控制模块:

asmlinkage int sys_msgget (key_t key, int msgflg)

函数参数:

   key:代表访问通信资源的权限

  msgflg:标志位。

函数返回类型:整型

函数功能:传递键值,标志位以及其他的参数,获得消息。

5.  消息传递的控制模块:

asmlinkage int sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)

函数参数:

   msqid:消息序列号

   cmd:处理消息的命令

   buf:指向msqid_ds的指针

函数返回类型:有关汇编连接的类型

函数功能: 系统调用。处理各种有关消息处理的命令

2.4 流程图

本程序的流程图如图2所示

图:Linux消息队列


                 消息传递的示意图

2.5 以实例说明运行过程

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#define MAX_LINE 80
#define MY_MQ_ID 1233

typedef struct
{
    long type; 
    int tag;
    int * m;
    //download_arg_t *;
    //upload_arg_t *;
}MY_TYPE_T;
int main(  )
    {
        int msgid,ret;
        int b;
        //create the message queue with the id MY_MQ_ID
        msgid=msgget( MY_MQ_ID,0666|IPC_CREAT );
        if( msgid>=0 )
             printf( "Created a Message Queue,message queue identifier is %d\n",msgid );
        //modify the size of message queue
        struct msqid_ds buf;
        ret=msgctl( msgid,IPC_STAT,&buf );
        printf( "The origianl size of queue is %d\n",buf.msg_qbytes );
       
        buf.msg_qbytes=1000;
        ret=msgctl( msgid,IPC_SET,&buf );
        if( ret==0 )
            printf( "Size sucessfully changed for queue,message queue identifier is %d\n",msgid );
        //send a message
        b = 5;
        MY_TYPE_T myMessage;
        myMessage.type=1L;
        myMessage.tag=2;  
        myMessage.m=&b;
        ret=msgsnd( msgid,( struct msgbuf* )&myMessage,sizeof( MY_TYPE_T ),0 );
        if( ret!=-1 )
            printf( "Message send successfully.\n" );
        //read a message
        MY_TYPE_T recMessage;
        ret=msgrcv( msgid,( struct msgbuf* )&recMessage,sizeof(MY_TYPE_T),1,0 );
        if( ret!=-1 )
            {
                printf( "\nRead a message from the queue\n" );
                printf( "Message Type:%ld\n",recMessage.type );
                printf( "Message Type:%d\n",recMessage.tag );
                printf( "Message Type:%d\n",*(recMessage.m) );
            }
        //destroy a message queue
        ret=msgctl( msgid,IPC_RMID,NULL );
        if( ret!=-1 )
            printf( "Message queue %d sucessfully removed.\n",msgid );
       
        return 0;
    }

相关推荐