c语言 - 我必须创建两个调度程序线程,并且我的代码中出现了分段错误,但我不明白为什么会这样。有人能帮忙吗?



好的,所以我现在的代码有点混乱,根本不是最佳的,所以很抱歉(一旦它工作,我会清理它(。

但基本上我必须实现一个长期和短期调度程序作为队列,元素是结构(进程(。每个调度程序都是使用多线程调用的,但是当我尝试运行长期调度程序时,我遇到了分段错误,我不确定为什么。我必须创建另一个结构,因为 pthread 只为它变成线程的函数接受一个输入,我需要为它提供两个队列。我认为问题出在那里的某个地方,但我只是看不出有什么问题。任何帮助将不胜感激。

这些是我的结构。

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <pthread.h>
struct Queue
{
struct Process *front, *rear;
};
struct Process
{
int pid, time;
struct Process* next;
};
struct args {
struct Queue* jqueue;
struct Queue* rqueue;
};

这些是队列的函数

struct Process* newProcess(int i)
{
struct Process* temp = (struct Process*)malloc(sizeof(struct Process));
temp->pid = i;
temp->time = (rand() % 30) + 1;
return temp;
}
struct Queue* createQueue()
{
struct Queue* queue = (struct Queue*) malloc(sizeof(struct Queue));
queue->front = queue->rear = NULL;
return queue;
}
void enqueue(struct Queue* queue, struct Process* proc)
{
if (queue->rear == NULL)
{
queue->front = queue->rear = proc;
return;
}
queue->rear->next = proc;
queue->rear = proc;
}
struct Process* dequeue(struct Queue* queue)
{
if (queue->front == NULL)
{
return NULL;
}
struct Process* temp = queue->front;
queue->front = queue->front->next;
if (queue->front == NULL)
{
queue->rear = NULL;
}
return temp;
}
int getSize(struct Process* front)
{
int count = 0;
struct Process* current = front;
while(current != NULL)
{
count++;
current = current->next;
}
return count;
}

这是长期调度程序函数,应作为单独的线程运行。 它将元素从作业队列移动到就绪队列

void *longTermScheduler(void *input)
{
sleep(1);
struct Process* current = ((struct args*)input)->jqueue->front;
printf("%d", current->pid);
while (current->next != NULL)
{
printf("[LTS] Job Queue: [Process %d: Time %d], ", current->pid, current->time);
current = current->next;
}
current = ((struct args*)input)->rqueue->front;
if((getSize(current)) == 0)
{
printf("[LTS] Ready Queue: EMPTY");
}
else
{
while (current->next != NULL)
{
printf("[LTS] Ready Queue: [Process %d: Time %d], ", current->pid, current->time);
current = current->next;
}
}
int c = getSize(((struct args*)input)->rqueue->front);
while(c < 6)
{
struct Process* temp = dequeue(((struct args*)input)->rqueue);
enqueue(((struct args*)input)->rqueue, temp);
printf("[LTS] Process %d removed from the Job Queue and inserted to the Ready Queue", temp->pid);
c++;
}
printf("[LTS] Ready Queue is Full, cannot enter more.");
current = ((struct args*)input)->jqueue->front;
while (current->next != NULL)
{
printf("[LTS] Job Queue: [Process %d: Time %d], ", current->pid, current->time);
current = current->next;
}
current = ((struct args*)input)->rqueue->front;
while (current->next != NULL)
{
printf("[LTS] Ready Queue: [Process %d: Time %d], ", current->pid, current->time);
current = current->next;
}
}

主要功能

int main()
{
int n = 1;
pthread_t thread1, thread2;
struct Queue* jobqueue = createQueue();
struct Queue* readyqueue = createQueue();
struct args *queues = (struct args *)malloc(sizeof(struct args));
queues->jqueue = jobqueue;
queues->rqueue = readyqueue;
while(n <= 11)
{
struct Process* newproc = newProcess(n);
enqueue(jobqueue, newproc);
n++;
}
struct Process* current = jobqueue->front;
while (current->next != NULL)
{
printf("[Kernel] Process %d created with Time = %dn", current->pid, current->time);
current = current->next;
}
printf("[Kernel] Long Term Scheduler Invokedn");
pthread_create(&thread1, NULL, longTermScheduler, (void *)queues);
pthread_join(thread1, NULL);
return 0;
}

OP 通过上面的注释发现了问题,但有一些代码建议可以使事情更容易阅读。

首先是关于malloc()的一些建议。您应该始终假设生成的内存块包含垃圾,因此您应该始终初始化重要内容。temp->next指针未初始化,这几乎肯定会引起问题。

此外,没有必要强制转换malloc()的结果,因为void *指针会自动转换为任何其他类型的数据指针。

虽然你可以通过类型名称来获取大小,但最好从它将要去的变量中派生它。sizeof *temp表示"temp指向的字节 # ",因此即使您将Process更改为其他类型,大小也始终正确。

struct Process* newProcess(int i)
{
struct Process* temp = malloc(sizeof *temp);
temp->pid = i;
temp->time = (rand() % 30) + 1;
temp->next = NULL;
return temp;
}

longTermScheduler函数中,有很多不需要的转换:

void *longTermScheduler(void *tempInput)
{
struct args *input = tempInput;
...

现在input不再是你必须到处投掷的虚空指针,而是指向你关心的真实类型的真实指针,所以你可以直接使用它。在整个代码中,这要容易得多,因为下一个代码片段将显示。

最后一点,直接权衡你发现的错误,代码中有太多的地方你相信你得到了一个有效的指针。

// in longTermScheduler
...
int c = getSize(input->rqueue->front);
while(c < 6)
{
struct Process* temp = dequeue(input->rqueue);
if (temp == NULL) break;  // CAREFUL HERE!
enqueue(input->rqueue, temp);
printf("[LTS] Process %d removed from the Job Queue and inserted to the Ready Queuen", temp->pid);
c++;
}

我想你建议它应该从作业队列而不是就绪队列中提取,但错误是相同的:如您所见,不检查有效的指针会带来不愉快的惊喜。

相关内容

最新更新