我正在编写一个程序来模拟CPU调度程序。因此,我正在实现一个双向链表以用作就绪队列。每当添加新进程时,都会创建一个进程控制块(PCB)并将其添加到就绪队列中。每个PCB都有一个独特的PID。因此,每当添加新PCB时,我都会将PID递增1。
pid += 1;
currentDevices[0].enqueuePCB(pid);
//currentDevices[0] represents the ready queue. There are other queues as well
这是我的enqueuePCB函数:
void device::enqueuePCB(int num)
{
pcb* newPCB = new pcb();
newPCB -> pid = num;
newPCB -> next = NULL;
newPCB -> prev = NULL;
if (head == NULL)
{
head = tail = newPCB;
queueLength += 1;
}
else
{
pcb* temp = tail;
newPCB -> next = tail;
temp -> prev = newPCB;
tail = newPCB;
queueLength += 1;
}
}
和我的打印功能
void device::snapReadyQueue()
{
pcb* temp = head;
cout << "PID: ";
while (temp != NULL)
{
cout << temp -> pid << " ";
temp = temp -> prev;
}
cout << endl;
}
当我测试我的程序时,只添加一个PCB并打印一个空白的“PiD:”。但是,一旦我开始添加更多PCB和打印,我实际上可以检索其他PCB的PID。例如,在第一次和打印之后再添加2个PCB将会得到我
PID:2 3
缺少1,我不明白为什么。我通过我的if else语句查看了enqueue,这看起来很有意义。我也试过使用单链表,但它不起作用。
更新 经过一些测试后,我意识到它可能与我在初始化队列之前使用的if-else语句有关。
if (processCount == 0)
{
cout << "Currently no processes in the ready queue.\nAvailable commands: A: ";
cin >> call;
if (call == "A")
{
pid = 1;
currentDevices[0].enqueuePCB(pid);
processCount += 1;
run();
}
}
else
{
cout << "Please enter call: ";
cin >> call;
if (call == "A")
{
pid += 1;
currentDevices[0].enqueuePCB(pid);
processCount += 1;
run();
}
我第一次入队时尝试打印头,我的程序崩溃了。然而,当我添加第二个PCB时,磁头指向PID 2。
答案 0 :(得分:2)
我认为将一个元素添加到列表中的代码是错误的,你说:
pcb* temp = tail;
newPCB -> next = tail;
temp -> prev = newPCB;
tail = newPCB;
queueLength += 1;
假设tail是指向列表最后一个元素的指针,我们可以跟踪这里发生的事情。现在让我们忘记temp
,告诉newPCB
它的下一个元素是尾(当前的最后一个元素)。接下来,您告诉tail
其前身是newPCB
,之后您将newPCB
设为尾部。因此,尾部是newPCB
,其前一个元素是NULL
,但它的下一个元素是之前的tail
。我想你的意思是:
tail -> next = newPCB;
newPCB -> prev = tail;
tail = newPCB;
答案 1 :(得分:1)
您是否在构造函数中将head和tail字段设置为NULL?如果不是这样,可能会导致device :: enqueuePCB内部出现问题。