Я очень новичок в языке C и Linux, и английский язык не является моим родным языком. Извините за это заранее.Реализация планировщика потоков round robin и thread cancel
Я работаю над школьным проектом, который должен реализовать плановый планировщик на linux, и у меня есть некоторые проблемы при реализации планировщика и thread_self.
Планировщик проверяет, пуста ли первая очередь, если да, задан временной срез и будильник (таймер). В противном случае найдите новый поток из готового списка, отправьте TCB нового потока, установите таймлис, переключите контекст на новый поток и установите будильник (таймер). Но в какой-то момент я все время получаю ошибку, и я не мог найти, где ее исправить.
Другое дело о thread_cancel. Функция int thread_cancel (thread_t tid) удаляет целевой tcb, и мне нужно найти tcb, используя tid. Я пробовал как
Thread* temp = getpid();
kill(pid, SIGKILL);
но я не мог понять, как удалить tcb из очереди. Пожалуйста, дайте мне лучшую идею!
Thread.h
typedef struct _Thread{
ThreadStatus status;
pid_t pid;
Thread* pPrev;
Thread* pNext;
}Thread;
Thread* ReadyQHead;
Thread* ReadyQTail;
-Queue
typedef struct _queue{
Thread* head;
Thread* tail;
unsigned int num;
} queue;
queue* runList;
queue* readyList;
queue* waitList;
-Queue.c
void enqueue(queue * q, Thread* tcb)
{
if(q->num == 0) {
q->head = tcb;
q->tail = tcb;
} else {
q->tail->pNext = tcb;
q->tail = tcb;
}
q->num ++;
}
Thread * dequeue(queue * q)
{
Thread * tmp;
if(q->num == 0) return NULL;
else if(q->num == 1) {
tmp = q->head;
q->head = NULL;
q->tail = NULL;
} else {
tmp = q->head;
q->head = q->head->pNext;
}
q->num --;
return tmp;
}
-Scheduler
void alarmHandler(int signal)
{
printf("Scheduler awake!!");
/*Do schedule*/
}
int RunScheduler(void)
{
//check if ready queue is empty
if(is_empty(readyList) != 0)
{
printf("this is weird");
signal(SIGALRM, alarmHandler);
}
else {
/*Look up a new thread from ready list*/
Thread* tmp = ReadyQHead;
/*send sigcont*/
kill(tmp->pid, SIGCONT);
//dispatch TCB of new thread
if(is_empty(runList) != 0 && runList->head->status == 0)
enqueue(readyList, tmp);
//pick thread at head of ready list as first thread to dispatch
tmp->status = 0; // tmp == runningTcb
printf("alive tcb : %d\n", tmp->pid);
ReadyQHead = dequeue(readyList);
//set timeslice
signal(SIGALRM, alarmHandler);
//context switch to new thread
_ContextSwitch(tmp->pid, ReadyQHead->pid);
}
while(1){
alarm(TIMESLICE);
}
return 0;
}
void _ContextSwitch(int curpid, int tpid)
{
kill(curpid, SIGSTOP);
kill(tpid, SIGCONT);
}
Можете ли вы опубликовать полную программу, потому что мне нужно проверить определение очереди и dequeue. –
@SumitGemini Я отредактировал! – user19283043
Обратите внимание, что вызов 'printf' в обработчике сигнала является злым, поскольку' printf' не является безопасным для асинхронного сигнала. – MirkoBanchi