C 我必须创建两个调度程序线程和I';我的代码中有一个分段错误,但我可以';我不明白这是为什么。有人能帮忙吗?
好吧,我现在的代码有点凌乱,根本不是最优的,所以对此表示歉意(一旦它工作起来,我会清理它) 但基本上,我必须实现一个长期和短期调度器,作为队列,元素是结构(进程)。每个调度程序都是使用多线程调用的,但是当我尝试运行longtermscheduler时,我会遇到一个分段错误,我不知道为什么。我必须创建另一个结构,因为pthread只为它要转换为线程的函数接受一个输入,我需要为它提供两个队列。我认为问题在某个地方,但我只是不知道哪里出了问题。任何帮助都将不胜感激 这些是我的结构C 我必须创建两个调度程序线程和I';我的代码中有一个分段错误,但我可以';我不明白这是为什么。有人能帮忙吗?,c,multithreading,struct,segmentation-fault,C,Multithreading,Struct,Segmentation Fault,好吧,我现在的代码有点凌乱,根本不是最优的,所以对此表示歉意(一旦它工作起来,我会清理它) 但基本上,我必须实现一个长期和短期调度器,作为队列,元素是结构(进程)。每个调度程序都是使用多线程调用的,但是当我尝试运行longtermscheduler时,我会遇到一个分段错误,我不知道为什么。我必须创建另一个结构,因为pthread只为它要转换为线程的函数接受一个输入,我需要为它提供两个队列。我认为问题在某个地方,但我只是不知道哪里出了问题。任何帮助都将不胜感激 这些是我的结构 #include &
#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;
};
这是longtermscheduler函数,应该作为单独的线程运行。它将元素从jobqueue移动到readyqueue
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;
}
}
void*长期调度器(void*输入)
{
睡眠(1);
结构进程*当前=((结构参数*)输入)->jqueue->front;
printf(“%d”,当前->pid);
while(当前->下一步!=NULL)
{
printf(“[LTS]作业队列:[进程%d:时间%d],”,当前->pid,当前->时间);
当前=当前->下一步;
}
当前=((结构参数*)输入)->rqueue->front;
如果((getSize(当前))==0)
{
printf(“[LTS]就绪队列:空”);
}
其他的
{
while(当前->下一步!=NULL)
{
printf(“[LTS]就绪队列:[进程%d:时间%d],”,当前->pid,当前->时间);
当前=当前->下一步;
}
}
intc=getSize((结构参数*)输入)->rqueue->front;
而(c<6)
{
结构进程*temp=dequeue((结构参数*)输入)->rqueue;
排队(((结构参数*)输入)->rqueue,temp;
printf(“[LTS]进程%d已从作业队列中删除并插入就绪队列”,temp->pid);
C++;
}
printf(“[LTS]就绪队列已满,无法输入更多。”);
当前=((结构参数*)输入)->jqueue->front;
while(当前->下一步!=NULL)
{
printf(“[LTS]作业队列:[进程%d:时间%d],”,当前->pid,当前->时间);
当前=当前->下一步;
}
当前=((结构参数*)输入)->rqueue->front;
while(当前->下一步!=NULL)
{
printf(“[LTS]就绪队列:[进程%d:时间%d],”,当前->pid,当前->时间);
当前=当前->下一步;
}
}
主要功能
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 = %d\n", current->pid, current->time);
current = current->next;
}
printf("[Kernel] Long Term Scheduler Invoked\n");
pthread_create(&thread1, NULL, longTermScheduler, (void *)queues);
pthread_join(thread1, NULL);
return 0;
}
intmain()
{
int n=1;
pthread_t thread1,thread2;
结构队列*jobqueue=createQueue();
结构队列*readyqueue=createQueue();
struct args*队列=(struct args*)malloc(sizeof(struct args));
队列->jqueue=jobqueue;
队列->rqueue=readyqueue;
而(n)锋;
while(当前->下一步!=NULL)
{
printf(“[内核]进程%d已创建,时间=%d\n”,当前->pid,当前->时间);
当前=当前->下一步;
}
printf(“[Kernel]调用的长期调度程序\n”);
pthread_创建(&thread1,NULL,longTermScheduler,(void*)队列);
pthread_join(thread1,NULL);
返回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
不再是一个你必须到处投射的空指针,而是一个指向你所关心的真正类型的真正指针,因此你可以直接使用它。正如下一个代码片段所示,这在整个代码中都要容易得多
最后一点,直接影响到你发现的bug,在代码中有太多地方你相信你得到了一个有效的指针
// 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 Queue\n", temp->pid);
c++;
}
//在longTermScheduler中
...
intc=getSize(输入->队列->前端);
而(c<6)
{
结构进程*temp=dequeue(输入->rqueue);
如果(temp==NULL)中断;//请小心!
排队(输入->rqueue,临时);
printf(“[LTS]进程%d已从作业队列中删除并插入就绪队列\n”,temp->pid);
C++;
}
我认为您建议它应该从作业队列而不是就绪队列中提取,但错误是一样的:正如您所看到的,不检查有效指针会带来不愉快的惊喜。OP通过上面的注释发现了问题,但是有一些代码建议会使事情更容易阅读 首先是关于
malloc()
的一些建议。您应该始终假设生成的内存块包含垃圾,因此您应该始终初始化重要内容。temp->next
指针未初始化,这几乎肯定会导致问题
此外,无需强制转换malloc()
的结果,因为void*
指针会自动转换为任何其他类型的数据指针
虽然您可以通过类型名获得大小,但最好从它将要使用的变量派生出来。sizeof*temp
表示“temp指向的字节数”,因此大小将始终保持不变
// 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 Queue\n", temp->pid);
c++;
}