2016-11-29 18 views
2

Я очень новичок в языке 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); 
} 
+0

Можете ли вы опубликовать полную программу, потому что мне нужно проверить определение очереди и dequeue. –

+0

@SumitGemini Я отредактировал! – user19283043

+0

Обратите внимание, что вызов 'printf' в обработчике сигнала является злым, поскольку' printf' не является безопасным для асинхронного сигнала. – MirkoBanchi

ответ

0

здесь является простым примером round robin

while(1) 
{ 
    process1(); 
    process2(); 
    process3(); 
    process4(); 
    .... 
    processN(); 
} 

что-нибудь более сложным, например, переключением контекста в то время как процесс «спящий» или переключения контекста во время ожидания ввода/вывода или контекст переключения, так как процесс должен быть запущен на по времени или из-за события прерывания добавляет огромную сложность.

Какова ваша цель/цель?