涉及循环调度的代码无法 运行 或给出分段错误(核心已转储)

Code in involving round robin scheduling fails to run or gives a segmentation fault(core dumped)

(C++) 我的代码应该模仿使用链表的循环 cpu 调度算法(因此接受带有时间的进程名称列表 ex:ProcessA 10,从时间中减去 3,如果结果大于 0,它被移到列表的末尾。这一直持续到进程时间达到 0,此时进程完成)。

我的程序接受并正确显示进程列表及其时间。所以我没有包含接受、创建和显示列表的代码。在显示用户输入的列表后的某处,程序由于某种原因突然结束。

我的输出:

[John@fish lab2]$ ./a.out
Enter your processes, to end press '^d'
ProcessA 4
Enter your processes, to end press '^d'
ProcessB 10
Enter your processes, to end press '^d'
ProcessC 6
Enter your processes, to end press '^d'
^d
Displaying the list of processes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ProcessA 4
ProcessB 10
ProcessC 6
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


我尝试修改 while 循环,因为我认为标志有问题,所以我将其从 while(print_flag) 更改为 while(true) 并在 else 条件下放置了一个 break 语句。

我的输出:

与上次输出相同,只是多了一行:'segmentation fault(core dumped)'

我不知道如何解决根本问题。感谢任何帮助。

#include <iostream>
#include <list>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string>

using namespace std;

volatile sig_atomic_t print_flag = false;

struct NodeType
{
    string value1; //process name
    int value2; //process time
    NodeType* next;
    
    void DisplayLinkedList(NodeType* head)
    {
        NodeType* p;

        p = head;   //initialize pointer p to point to the first node in the linked list 

        cout << "Displaying the list of processes: " << endl;
        cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
        while (p != NULL)
        {
            cout << p->value1 << " " << p->value2 << endl;
            p = p->next;  //update p to point to next node in the linked list ... 
        }
        cout << "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^" << endl;
        cout << " " << endl;
    }

    void createnode(NodeType*& head, string x, int y)
    {
        NodeType* p = new NodeType;
        
        
        if (head == NULL)
        {
            p->value1 = x;
            p->value2 = y;
            p->next = NULL;
            head = p;
        }
        else
        {
            p = head;
            while (p->next != NULL)
                p = p->next;
            p->next = new NodeType;
            p = p->next;
            p->value1 = x;
            p->value2 = y;
            p->next = NULL;
            
        }
    }

    bool IsEmpty(NodeType* h) const
    {
        return h == NULL;
    }

    void DeleteNode(NodeType*& head)
    {
        NodeType* p = head;
        head = head->next;
        delete p;
    }

    
    void roundrobin(NodeType*& head)
    {
        head->value2 -= 3;
        if (head->value2 == 0) // no time remaining 
        {
            cout << head->value1 << " Finished" << endl;
            DeleteNode(head);
        }
        else // time remaining
        {
            NodeType* p = head;
            p->next = NULL;
            head = head->next;
            NodeType* q = head;
            while (q->next != NULL)
                q = q->next;
            q->next = p;
        }
    }
};

void handle_alarm(int sig) // interrupt handler, manipulates flags to allow roundrobin to run
{
    print_flag = true;
}


int main()
{
    NodeType* head = NULL;
    NodeType a;
    string v, x, y;
    int argc = 0;
    int z = 0;
    

    while(true)
    {
        cout << "Enter your processes, to end press '^d' " << endl;
        getline(cin, v);
        if (v == "^d")
            break;
        //cin >> a;
        int index = v.find(" "); 
        x = v.substr(0, index); 
        y = v.substr(index + 1, v.length());
        
        z = stoi(y);
        a.createnode(head, x, z);

        argc++;
    }

    a.DisplayLinkedList(head);
    
    signal(SIGALRM, handle_alarm);
    alarm(3);
    while (print_flag)
    {
        
            if (a.IsEmpty(head) == false) // list not empty
            {
                a.roundrobin(head);
                a.DisplayLinkedList(head);
            }
            else
            {
                cout << "No more processes left" << endl;
                print_flag = false;
            }
        
        //print_flag = false;
        alarm(3);
    }
    
    return 0;
}

我认为您需要对 roundrobin 函数进行一些小改动才能使其正常工作:

您需要更新条件以检查流程是否已完成 head->value2 <= 0 而不是 head->value2 == 0 因为 head->value2 == 0 似乎只适用于 value2 可以被 3 整除的任何进程,并且它将错过其他进程,因为它们将减去负数通过这个表达式 head->value2 -= 3

您还需要将 p->next = NULL; 行放在 head = head->next; 之后而不是之前。否则,head 将始终是 NULL,因为 p 当前是 head

最后,在切换到下一个进程之前,您需要检查 head 是否是唯一剩下的进程 (head->next != NULL)。否则,如果 head->nextNULL,你会让你的 head 变成 NULL,导致分段错误

  void roundrobin(NodeType*& head)
  {
    head->value2 -= 3;
    if (head->value2 <= 0) // no time remaining 
    {
      cout << head->value1 << " Finished" << endl;
      DeleteNode(head);
    }
    else // time remaining
    {
      NodeType* p = head;
      if (head->next != NULL) {
        head = head->next;
        p->next = NULL;
        NodeType* q = head;
        while (q->next != NULL)
          q = q->next;
        q->next = p;
      } 
    }
  }