南京航空航天大学2020-2021学年操作系统实验考试题目

南京航空航天大学2020-2021学年操作系统实验考试题目

链接:https://github.com/LM0624/2021NUAA_OS_EXAM

T1.c

// + 补全生产者、计算者、消费者程序
//   - 完成函数 buffer_init
//   - 完成函数 buffer_get
//   - 完成函数 buffer_put
//   - 补全函数 main
//     * 创建生产者、计算者、消费者
//
// + 程序最终输出
//   - 生产者输出 a b c d e f g h
//   - 消费者输出 A B C D E F G H
//   - 消费者输出 A B C D E F G H
//   - 两者交叉输出 
//
// + 不准对函数 produce 、函数 compute、 函数 consume 进行任何改动
//   - 如果改动,则该题没有分数
//
// + 本题对 buffer 进行了抽象和封装
//   - buffer_pc 连接 producer 和 computer
//   - buffer_cc 连接 computer 和 consumer 

#include <stdio.h>
#include <pthread.h>
#include <ctype.h>

#define CAPACITY 4      // 缓冲区的最大容量

struct buffer {
    int data[CAPACITY];
    int in;             // 缓冲区的写指针
    int out;            // 缓冲区的读指针
    pthread_mutex_t mutex;
    pthread_cond_t wait_empty_buffer;
    pthread_cond_t wait_full_buffer;
};

// 初始化 buffer,需要初始化用于同步的字段 
void buffer_init(struct buffer *buffer)
{
    buffer->in = 0;
    buffer->out = 0;
}

// 判断缓冲区是否为空
int buffer_is_empty(struct buffer *buffer)
{
    return buffer->in == buffer->out;
}

// 判断缓冲区是否为满
int buffer_is_full(struct buffer *buffer)
{
    return (buffer->in + 1) % CAPACITY == buffer->out;
}

// 向缓冲区中追加一个数据,如果缓冲区为满,则等待
void buffer_put(struct buffer *buffer, int item)
{
}

// 从缓冲区中取走一个数据,如果缓冲区为空,则等待
int buffer_get(struct buffer *buffer)
{
}

#define ITEM_COUNT (2 * CAPACITY)

struct buffer buffer_pc, buffer_cc;

void *produce(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
        item = 'a' + i;
        printf("produce item: %c\n", item);
        buffer_put(&buffer_pc, item);
    }
    return NULL;
}

void *compute(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
        item = buffer_get(&buffer_pc); 
        item = toupper(item);
        printf("    compute item: %c\n", item); 
        buffer_put(&buffer_cc, item);
    }
    return NULL;
}

void *consume(void *arg)
{
    int i;
    int item;

    for (i = 0; i < ITEM_COUNT; i++) { 
        item = buffer_get(&buffer_cc); 
        printf("        consume item: %c\n", item); 
    }
    return NULL;
}

int main()
{ 
    buffer_init(&buffer_pc);
    buffer_init(&buffer_cc);

    pthread_t producer_tid;
    pthread_t computer_tid;
    pthread_t consumer_tid;

    
    pthread_create(&producer_tid, NULL, produce, NULL);
    pthread_create(&computer_tid, NULL, compute, NULL);
    pthread_create(&consumer_tid, NULL, consume, NULL);

    pthread_join(consumer_tid,NULL);

    return 0;
}

T2.c

// 实现命令 mygrep string file
// + 该命令逐行读取文件,如果行包括目标字符串,则打印该行
// + 该命令有两个命令行参数
//   - 参数 string,要搜索的字符串
//   - 参数 file,要查找的文件名
// 
// 例子,在文件 /etc/passwd 中查找字符串 root,打印包含该字符串的行
// $ ./mygrep root /etc/passwd
// root:x:0:0:root:/root:/bin/bash
//
// 提示,可以使用函数 strstr 在字符串中查找字符串
// https://www.runoob.com/cprogramming/c-function-strstr.html

T3.c

// + 实现函数 list_visit
//   - 主程序遍历链表 list 的每个节点
//   - 对每个节点创建一个子线程,在这道题目中,总共创建 7 个子线程
//   - 在每个子线程中,打印 node->data
//
// + 实现函数 wait_sub_threads
//   - 等待所有的子线程执行完毕
//   - 在 list_visit 时,需要记录下所有线程的 ID,记录在全局变量中
//   - 在 wait_sub_threads 中使用 pthread_join
//
// + 程序可能的输出结果
//   - 字符 a b c d e f g 每个出现一次,出现的顺序可能是随机的  
//   - END 一定是最后出现
//   a
//   d
//   b
//   e
//   c
//   f
//   g
//   END
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

struct node {
    char data;
    struct node *next;
};

pthread_t workers[7];

struct node *node_create(char data)
{
    struct node *node = malloc(sizeof(struct node));
    node->data = data;
    node->next = NULL;
    return node;
}


void list_visit(struct node *list)
{
}

// 遍历算法,供参考
void list_print(struct node *list)
{
    struct node *node = list;
    while (node) {
        printf("%c\n", node->data);
        node = node->next;
    }
}

void wait_sub_threads()
{
}

int main()
{
    struct node *list = NULL;
    for (char data = 'g'; data >= 'a'; data--) {
        struct node *node = node_create(data);
        node->next = list;
        list = node;
    }

    list_print(list);
    wait_sub_threads();

    puts("END");
    return 0;
}

T4.c

// 通过 fork/exec/pipe/dup 实现 cat </etc/passwd | wc -l >result.txt 
//
// + 父进程创建子进程
//   - 在父进程中实现功能 cat </etc/passwd
//   - 在子进程中实现功能 wc -l >result.txt
//   - 不能实现为
//     * 在子进程中实现功能 cat </etc/passwd
//     * 在父进程中实现功能 wc -l >result.txt
//
// + 该题不要求实现一个通用的 shell 程序
//   - 不需要使用 strtok 对字符串进行分割处理
//   - 假设字符串已经分割处理好了
//     * 父进程,使用 execlp("cat") 执行命令,使用 open("/etc/passwd") 打开文件
//     * 子进程,使用 execlp("wc") 执行命令,使用 open("result.txt") 打开文件
//
// + 请严格按要求完成
//   - 把作业 sh3.c 的内容复制过来,是没有分数的
  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值