我的问题要求根据给定的量子时间间隔打印出每个过程的所有信息.任何正在处理的过程都放在顶部,否则放在底部.如果该过程已完成处理,则不会再打印.

我的意见是:

char  name[50][10] = {"A","B","C","D","E"}; // process names
int  btime[] = {9,7,8,5,3}; // process burst times
int n = 5;

预期输出:

Round robin scheduling with time quantum = 2
0: (A,9,9) (B,7,7) (C,8,8) (D,5,5) (E,3,3)
2: (B,7,7) (C,8,8) (D,5,5) (E,3,3) (A,9,7)
4: (C,8,8) (D,5,5) (E,3,3) (A,9,7) (B,7,5)
6: (D,5,5) (E,3,3) (A,9,7) (B,7,5) (C,8,6)
8: (E,3,3) (A,9,7) (B,7,5) (C,8,6) (D,5,3)
10: (A,9,7) (B,7,5) (C,8,6) (D,5,3) (E,3,1)
12: (B,7,5) (C.8.6) (D.5.3) (E,3,1) (A,9,5)
14: (C,8,6) (D,5,3) (E,3,1) (A,9,5) (B,7,3)
16: (D,5,3) (E,3,1) (A,9,5) (B.7,3) (C,8,4)
18: (E,3,1) (A,9,5) (B,7,3) (C,8,4) (D,5,1)
19: (A,9,5) (B,7,3) (C,8,4) (D,5,1)
21: (B,7,3) (C,8,4) (D,5,1) (A,9,3)
23: (C,8,4) (D,5,1) (A,9,3) (B,7,1)
25: (D,5,1) (A,9,3) (B,7,1) (C,8,2)
26: (A,9,3) (B,7,1) (C,8,2)
28: (B.7.1) (C,8,2) (A,9,1)
29: (C,8,2) (A,9,1)
31: (A,9,1)

我的代码:

#include <stdio.h>

int main()
{
    char name[50][10] = {"A", "B", "C", "D", "E"}; // process names
    int btime[] = {9, 7, 8, 5, 3};                // process burst times
    int n = sizeof btime / sizeof btime[0];
    int quantum = 2;
    int wt[n], i;
    int rem_bt[n];
    for (i = 0; i < n; i++)
        rem_bt[i] = btime[i];

    printf("Round robin scheduling with time quantum = %d\n", quantum);
    int t = 0;
    while (1)
    {
        int done = 1;
        for (i = 0; i < n; i++)
        {
            if (rem_bt[i] > 0)
            {
                done = 0;
                if (rem_bt[i] > quantum)
                {
                    printf("%d: (%s,%d,%d) \n", t, name[i], btime[i], rem_bt[i]);
                    rem_bt[i] -= quantum;
                    t += quantum;
                }
                else
                {
                    printf("%d: (%s,%d,%d) \n", t, name[i], btime[i], rem_bt[i]);
                    t += rem_bt[i];
                    wt[i] = t - btime[i] - rem_bt[i];
                    rem_bt[i] = 0;
                }
            }
        }
        if (done == 1)
        {
            break;
        }
        printf("\n");
    }

    return 0;
}

我被困在打印所有时间线的步骤中,我只能打印出关于正在运行的进程的信息,但不能打印出关于其他停止的进程的信息.

我的输出:

0: (A,9,9) 
2: (B,7,7) 
4: (C,8,8)
6: (D,5,5)
8: (E,3,3)
10: (A,9,7)
12: (B,7,5) 
14: (C,8,6) 
16: (D,5,3) 
18: (E,3,1)
19: (A,9,5)
21: (B,7,3) 
23: (C,8,4)
25: (D,5,1) 
26: (A,9,3) 
28: (B.7.1) 
29: (C,8,2) 
31: (A,9,1)

我想知道你的建议,非常感谢!

推荐答案

对于初学者来说,您总是 for each 未用尽的进程打印当前时钟和换行符.您需要将这些信息分成不同的打印,每set个进程只打印一次时钟和换行符.

此外,您总是从数组的开始迭代到数组的结尾,这意味着您的进程列表将始终从索引最低的未耗尽的进程开始,而不是从未耗尽的next个进程开始.


一种方法是使用remainder operator(%)将索引钳制到适当的范围,进而管理数组中的当前全局位置.这让您可以cycle遍历数组中的位置;这意味着您可以从中间开始,迭代到末尾,绕回到数组的开头,然后通过单独跟踪迭代的总次数来迭代回到中间.

一个基本的算法是,在每个处理点:

  • 查找next未耗尽的进程,更新全局索引.
    • 跟踪判断的进程数.
      • 如果所有进程耗尽,则退出.
  • 打印当前时钟.
  • 打印当前流程,并更新其时间使用情况.
    • 使用处理时间更新时钟.
  • 使用本地索引打印其余进程.

更激进的算法可能会将数组元素移到用尽的数组元素上,或者使用可以更自由地操作的不同数据 struct (例如,使用挂起和已完成进程的两个链表).


一些额外的建议是将您的processes表示为一个由structures组成的数组,而不是三个单独的碎片数据array.从无符号类型的Angular 来考虑这个问题也可能更容易,因为时间(几乎)总是advancing.在下面的示例中,我们处理的是elapsed time,而不是remaining time.


一个相当完整的例子:

#include <stdio.h>

struct entry {
    const char *name;
    const unsigned target_time;
    unsigned elapsed_time;
};

static void print_entry(const struct entry *e)
{
    printf(" (%s,%u,%u)", e->name, e->target_time, e->target_time - e->elapsed_time);
}

int main(void)
{
    struct entry entries[] = {
        { "A", 9, 0 }, { "B", 7, 0 }, { "C", 8, 0 }, { "D", 5, 0 }, { "E", 3, 0 }
    };
    const size_t n_entries = sizeof entries / sizeof *entries;
    const unsigned processing_time = 2;

    unsigned tick = 0;
    size_t index = 0;

    printf("Round robin scheduling with time quantum = %u\n", processing_time);

    while (1) {
        size_t n = n_entries;
        struct entry *entry;

        /* find next */
        do {
            entry = entries + index;
            index = (index + 1) % n_entries;
        } while (entry->elapsed_time >= entry->target_time && --n);

        /* none found, we're done */
        if (!n)
            break;

        printf("%u:", tick);
        /* print entry before it is processed */
        print_entry(entry);

        /* process time slice */
        entry->elapsed_time += processing_time;

        /* clamp elapsed time, and adjust tick */
        if (entry->elapsed_time > entry->target_time) {
            tick += entry->elapsed_time - entry->target_time;
            entry->elapsed_time = entry->target_time;
        } else {
            tick += processing_time;
        }

        /* print any remaining processes */
        for (size_t i = index; --n; i = (i + 1) % n_entries) {
            entry = entries + i;

            if (entry->elapsed_time < entry->target_time)
                print_entry(entry);
        }

        putchar('\n');
    }
}

输出:

Round robin scheduling with time quantum = 2
0: (A,9,9) (B,7,7) (C,8,8) (D,5,5) (E,3,3)
2: (B,7,7) (C,8,8) (D,5,5) (E,3,3) (A,9,7)
4: (C,8,8) (D,5,5) (E,3,3) (A,9,7) (B,7,5)
6: (D,5,5) (E,3,3) (A,9,7) (B,7,5) (C,8,6)
8: (E,3,3) (A,9,7) (B,7,5) (C,8,6) (D,5,3)
10: (A,9,7) (B,7,5) (C,8,6) (D,5,3) (E,3,1)
12: (B,7,5) (C,8,6) (D,5,3) (E,3,1) (A,9,5)
14: (C,8,6) (D,5,3) (E,3,1) (A,9,5) (B,7,3)
16: (D,5,3) (E,3,1) (A,9,5) (B,7,3) (C,8,4)
18: (E,3,1) (A,9,5) (B,7,3) (C,8,4) (D,5,1)
19: (A,9,5) (B,7,3) (C,8,4) (D,5,1)
21: (B,7,3) (C,8,4) (D,5,1) (A,9,3)
23: (C,8,4) (D,5,1) (A,9,3) (B,7,1)
25: (D,5,1) (A,9,3) (B,7,1) (C,8,2)
26: (A,9,3) (B,7,1) (C,8,2)
28: (B,7,1) (C,8,2) (A,9,1)
29: (C,8,2) (A,9,1)
31: (A,9,1)

C++相关问答推荐

CC crate 示例不会与C函数链接

ISO_C_BINDING,从Fortran调用C

如何设置指针指向在函数中初始化的复合文字中的整数?

编译的时候g++通常会比GCC慢很多吗?

如何一次获取一个字符

使用额外的公共参数自定义printf

C:fopen是如何实现二进制模式和文本模式的?

为什么C语言允许你使用var =(struct NAME){

在C中将通用字符名称转换为UTF-8

将 struct 变量赋给自身(通过指针取消引用)是否定义了行为?

双指针指向常量双指针的指针类型赋值不兼容

我怎么才能用GCC编译一个c库,让它包含另一个库呢?

在WSL关闭/重新启动后,是什么原因导致共享对象依赖关系发生更改?

如何读取文件并将内容保存在字符串中?(在C语言中,没有崩溃或核心转储错误)

如何在C++中安全地进行浮点运算

如何在VSCode中创建和使用我自己的C库?

为什么编译器不能简单地将数据从EDI转移到EAX?

我可以使用Windows SDK';s IN6_IS_ADDR_LOOPBACK等,尽管没有文档?

Struct 内的数组赋值

Linux memcpy 限制关键字语法