操作系统作业完全攻略手册

第一次作业鸽了

建议自己百度git怎么用,linux怎么装

第二次作业

这次软工作业主要是完成基本的shell编程,同时在linux下运行并截图

步骤一:完成shell编程(这是网上的代码。。。等大家这次作业都交完了我再放我的代码,讲道理这部分建议自己写,不然大家都一样的就有点尴尬)

注意:更改main函数中的printf(“osh>”);
要改成老师要求的那样

#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
#define MAX_LINE 80
int input(char* str);
int str_to_args(char* str,char* args[],int str_num);
void display_history(int history_front,int history_rear);
void add_history(char* str,int* front,int* rear);
char history[10][MAX_LINE];//history queue
int input(char* str){
	char c;
	int i = 0;
	while((c = getchar())!='\n' && i<MAX_LINE){
		str[i] = c;
		i++;
	}
	if(i == MAX_LINE && c != '\n'){//when error
		printf("over maximum length!");
		return 0;
	}	
	else{
		str[i] = 0;
		return i;
	}
}

int str_to_args(char* str,char* args[],int str_num){
	const char s[2] = " ";
	int i = 0;
	char* temp;

	temp = strtok(str,s);
	while(temp != NULL){
		args[i] = (char*)malloc(strlen(temp));
		strcpy(args[i],temp);
		i++;
		temp = strtok(NULL,s);
	}
	args[i] = 0;
	return i;
}
void display_history(int history_front,int history_rear){
	int i;
	for(i = history_front;i < history_rear;i++){
		printf("%d\t%s\n",history_rear - i,history[i%10]);
	}
}
void add_history(char* str,int* front,int* rear){
	strcpy(history[*rear % 10],str);//add
	*rear = *rear+1;
	if(*rear - *front > 10)
		*front++;
}

int main(void){
	char* args[MAX_LINE/2+1];//execvp's argslist
	int should_run = 1;
	int args_num = 0;

	char str[MAX_LINE];// user input
	int str_num;

	int history_front = 0;
	int history_rear = 0;
	
	int i = 0;
	int background = 0;
	int pid_status;

	while(should_run){
		printf("osh>");
		fflush(stdout);
		
		str_num = input(str);//get user input

		if(str_num == 0){//no input
			continue;
		}
		if(strcmp(str,"exit")== 0){//exit
			should_run = 0;
			continue;
		}
		if(strcmp(str,"history") == 0){//display history
			display_history(history_front,history_rear);
		}
		if(strcmp(str,"!!") == 0){//use recent command
			if(history_rear != 0){
				strcpy(str,history[(history_rear -1) % 10]);
				str_num = strlen(str);
			}
			else{
				printf("No commands in history.\n");
			}
		}
		else if(str[0] == '!'){//use history command
			if(str[1] <= '0' || str[1] > '9' || (str[1]-'0') > history_rear-history_front){
				printf("No such command in history.\n");
			}
			else if(str[1] == '1'){
				if(str[2] == '0')
					strcpy(str,history[history_front %10]);
				else if(str[2] == 0)
					strcpy(str,history[(history_rear-1) %10]);
				else
					printf("No such command in history.\n");
			}
			else
				strcpy(str,history[history_rear - str[1] + '0' -1]);
		}

		add_history(str,&history_front,&history_rear);//add to history

		args_num = str_to_args(str,args,str_num);

		if(strcmp(args[args_num-1],"&") == 0){
			background = 1;
			args_num--;
			args[args_num] = NULL;
		}

		pid_t pid = fork();
		if(pid == 0){
			pid_status = execvp(args[0], args);
		}
		else{
			if(background == 1){
				printf("%d is running in background %s \n",pid,str);
			}
			else{
				wait(&pid_status);
			}
		}
		background  = 0;
	}
	return 0;
}


步骤二:安装 gcc和vim 在linux 下运行测试

Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。

简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具。

安装vim和gcc

安装vim代码

sudo apt-get install vim-gtk

vim教程参考: vim教程
执行后大概如下:

请添加图片描述
联网并输入密码即可完成安装
安装gcc代码

sudo apt install gcc

一样的操作

用vim生成Shell.c文件

代码如下

vim Shell.c

之后会进入如下界面:
请添加图片描述

然后按" i “进入插入文本模式,右键复制粘贴将上述代码粘到文本中
按ESC退出该模式
输入” :wq "将文件保存并退出
请添加图片描述
请添加图片描述

生成编译文件

gcc Shell.c -o Shell

在linux下编译测试

./Shell

此时我们界面应该如下:
请添加图片描述

这时我们就可以测试运行我们的代码了

步骤三:使用make编写makefile文件并运行

运行如下代码创建Makefile文件

vim Makefile

将Makefile文件中粘入如下代码(vim操作基本相同)
这是最简单的一种编译方法,详情可以参照make教程

all: Shell
Shell: Shell.c
	gcc -o Shell Shell.c
clean:
	rm -rf *.o Shell

此时还是进入刚才的界面,与刚才不同的是,这次我们通过调用makefile文件来进行编译
输入如下命令

make

此时我们再运行

./Shell

在相应位置截图即可,git操作不再申明,哪里有问题可以留言

第三次作业

我们更改Makefile为如下内容(以下部分未测试 ,慎用)

all: Test1 Test2
Test1: test1.c
	gcc test1.c -lpthread -o test1
Test2: test2.c
	gcc test2.c -lpthread -o test2
clean:
	rm -rf *.o Test1

在同一文件夹下修改test1.c为如下内容
以下为生产者代码

#include  <stdio.h>
#include  <stdlib.h>
#include <unistd.h>
#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>


#include <pthread.h> 
#include <semaphore.h>
static pthread_mutex_t lock_x;
#define BUFFER_SIZE 100

#define TRUE  1
#define FALSE 0

/* Shared Memory Layout */
/*
*    | counter[0] | counter[1] | status | Product[0] | Product[1] |......| Product[99] |
*/

/* FLAGS For communication */
#define STATUS_READY	0
#define STATUS_RUNNING	1
#define STATUS_COMPLETE	2


#define PRODUCER 0
#define CONSUMER 1

struct Product
{
	int Id;
	char Name[32];
	int Value; 
};
/* Shared Memory Global Variables */
key_t          shmKey;
int            shmId;
void          *shmPtr;
void shmInit()
{
    shmKey = ftok(".", 'x');
    shmId = shmget(shmKey, sizeof(int)*3 + sizeof(struct Product) * BUFFER_SIZE, 0666);
    if (shmId < 0) {
        printf("*** shmget error (consumer) ***\n");
        exit(1);
    }

    printf("Consumer has received a shared memory.\n");

    shmPtr = shmat(shmId, NULL, 0);

    if ((int) shmPtr == -1) {
        printf("*** shmat error (client) ***\n");
        exit(1);
    }
}

void shmClean()
{
     shmdt((void *) shmPtr);
     printf("Consumer has detached its shared memory...\n");
     printf("Consumer exits...\n");
}

/* Shared Memory Layout */
/*
*    | counter[0] | counter[1] | flag[PRODUCER] | flag[CONSUMER] | turn | status | Product[0] | Product[1] |......| Product[99] |
*/

void  main(void)
{
    


    pthread_mutexattr_t lock_x;
    int ret;
    pthread_mutexattr_t mattr;
    //ret = pthread_mutexattr_init(&lock_x); /* * resetting to its default value: private */
   pthread_mutexattr_init(&mattr);
    pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&lock_x, &mattr);
     struct Product *buffer;
     int           *counter;
     int           *status;

     int out = 0;

     struct Product next_consumed;
     
     shmInit();
     counter = (int*)shmPtr;

     status = counter + 2;

     buffer = (struct Product*)(status + 1);

     printf("Counter:%d\t%d\n",counter[0],counter[1]);
     printf("Consumer has attached the shared memory...\n");

     if( *status == STATUS_READY )
	*status = STATUS_RUNNING;
     while(TRUE)
     {
         while( counter[0] == 0 )
             ;
         pthread_mutex_lock(&lock_x);
         next_consumed = buffer[ out ];
         out = (out + 1) % BUFFER_SIZE;


         counter[0]--;
         counter[1]--;
 

         printf("Consume the Product:\n\tId:%d\n\tName:%s\n\tValue:%d\n",
                next_consumed.Id,
                next_consumed.Name,
                next_consumed.Value);

	 if(counter[0] != counter[1])
	 {
             *status = STATUS_COMPLETE;
             printf("counter[0]=%d\tcounter[1]=%d\n", counter[0], counter[1]);
	     break;
         }
 pthread_mutex_unlock(&lock_x);
     }

     shmClean();

     exit(0);
}

修改test2.c为以下内容

#include  <stdio.h>
#include  <stdlib.h>
#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>

#include <pthread.h>

#include <semaphore.h>
#define BUFFER_SIZE 100
static pthread_mutexattr_t lock_x;
#define TRUE  1
#define FALSE 0

/* Shared Memory Layout */
/*
*    | counter[0] | counter[1] | status | Product[0] | Product[1] |......| Product[99] |
*/

/* FLAGS For communication */
#define STATUS_READY	0
#define STATUS_RUNNING	1
#define STATUS_COMPLETE	2


#define PRODUCER 0
#define CONSUMER 1

struct Product
{
	int Id;
	char Name[32];
	int Value; 
};
/* Global Shared Memory Variables */
key_t shmKey;
int   shmId;
void *shmPtr;

void shmInit()
{
     shmKey = ftok(".", 'x');

     shmId = shmget(shmKey, sizeof(int)*3  + sizeof(struct Product) * BUFFER_SIZE, IPC_CREAT | 0666);
     
     if (shmId < 0) {
          printf("*** shmget error (server) ***\n");
          exit(1);
     }
     
     printf("Produce create a buffer of size %d.\n", BUFFER_SIZE);
     
     shmPtr =  shmat(shmId, NULL, 0);
     if ((int) shmPtr == -1) {
          printf("*** shmat error (Producer) ***\n");
          exit(1);
     }
}

void shmClean()
{
     shmdt((void *) shmPtr);
     printf("Producer has detached its shared memory...\n");
     shmctl(shmId, IPC_RMID, NULL);
     printf("Producer has removed its shared memory...\n");
     printf("Producer exits...\n");
}

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

    int ret;
    pthread_mutexattr_t mattr;
    //ret = pthread_mutexattr_init(&lock_x); /* * resetting to its default value: private */
    pthread_mutexattr_init(&mattr);
    pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
    pthread_mutex_init(&lock_x, &mattr);
    struct Product  *buffer;
    int* counter;
    int  in = 0;

    int* status;

    struct Product product;
    int productId = 1;

    shmInit();

/* Shared Memory Layout */
/*
*    | counter[0] | counter[1] | status | Product[0] | Product[1] |......| Product[99] |
*/

    counter = (int*)shmPtr;
    status = counter + 2;

    buffer = (struct Product*)(status + 1);

    printf("Initialize shared variables...\n");
    counter[0]=0;
    counter[1]=0;

    *status = STATUS_READY;

    while(TRUE)
    {
        if( *status == STATUS_COMPLETE )
        {
            printf("Consumer exit.\n");
            break;
        }
     pthread_mutex_lock(&lock_x);
        /* produce a new product */
        product.Id = productId++;
        sprintf(product.Name, "N:%d",product.Id);
        product.Value = product.Id;
        printf("Produced new product %d\n", product.Id);

        while(counter[0] == BUFFER_SIZE)
            ;
        

        buffer[in] = product;
        in = (in + 1) % BUFFER_SIZE;
       

        counter[0] ++;
        counter[1] ++;
        pthread_mutex_unlock(&lock_x);

    }

    shmClean();

    exit(0);
}

然后执行make
就行了

写完不更

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值