代码之家  ›  专栏  ›  技术社区  ›  Ash

被分割错误踢屁股

  •  1
  • Ash  · 技术社区  · 14 年前

    这是我的代码:

    #include "./shared.h"
    #include "./scheduler.h"
    
    PCB_entry      *ready_q ;
    PCB_entry      *ready_q_tail;
    
    /*
     * file name priority.c
     *
     * The functions in this file implement a "priority"
     * scheduling scheme. 
     *
     * Functions provided and brief descriptions:
     *
     * PCB_entry * schedule_next (void) - returns next process for CPU
     * 
     * int insert_new (PCB_entry * proc) - insert new process into queue
     *
     * void list_q (void) - debugging function lists queue contents
     *
     * int re_insert (PCB_entry * proc, int run_time) - put process back
     *                 into correct queue after a run on the CPU 
     *
     * int init_q (void) - initialise queue(s)
     *
     */
    
    
    double pwr (double x, double y)
    {
        double i, p;
        p = 1;
        for (i = 1; i <= y; ++i){
            p = p * x;
        }
        return p;
    }
    
    
    /*
     * Function Schedule_next: priority
     * 
     * Called by the central simulation system Returns a 
     * pointer to the PCB entry for the "process" that 
     * should be put on the CPU next
     * 
     */
    PCB_entry *
    schedule_next (void)
    {
       /* if ready_q is null, there are no processes in the system */
       if (ready_q == NULL)
         {
        return NULL;
         }
       else
         { 
           PCB_entry *next;
           PCB_entry *best_proc;
    
            next = ready_q;
            best_proc = next;
               while (next != NULL)
                 {              /* traverse to the end of the list */
    
                if (next->current_priority < best_proc->current_priority) {
                    best_proc = next;   
                }
                next = next->f_link;
               }
            if (best_proc == NULL) {
                return NULL;
            }
    
            if (best_proc->b_link != NULL){
                best_proc->b_link->f_link = best_proc->f_link;
                if (best_proc->f_link != NULL) {
                    best_proc->f_link->b_link = best_proc->b_link;
                }
            } else {
    
                ready_q = best_proc->f_link;
    
    
                if (ready_q != NULL)    /* don't try to de-reference a NULL
                                         * pointer */
                   ready_q->b_link = NULL;  /* first process in the queue
                                             * always has a NULL back
                                             * link */
                best_proc->f_link = NULL;   /* just to be tidy -- set both links
                             * in the PCB */
                /* entry that will be returned to NULL */
                best_proc->b_link = NULL;
            }
    
            return best_proc;
    
        }
    }
    
    /*
     * Function insert_new: Non-preemptive round-robin
     * 
     * Insert a new "process" into the scheduling queue
     * 
     * Accepts a pointer to a PCB entry that will be inserted
     * into the queue returns either OK or NotOK to indicate 
     * success or failure
     * 
     * Since this is FCFS priority scheduling, the new process is
     * simply slotted in at the end of the queue
     * 
     */
    int
    insert_new (PCB_entry * proc)
    {
    
       if (ready_q == NULL)
         {              /* no entries in table */
        ready_q = proc;     /* insert at the head of the list */
        proc->b_link = NULL;
        proc->f_link = NULL;
        ready_q_tail = ready_q;
        return OK;
         }
       else
         {
    
            ready_q_tail->f_link = proc; /* Set tail of list pointer */
            proc->f_link = NULL;         /* New tail of list to NULL */
            proc->b_link = ready_q_tail; /* Set the b_link of the new process to previous last record of the list */
            ready_q_tail = proc;         /* Set the tail reference to the new pointer */
        return OK;
         }
    #pragma error_messages (off,E_STATEMENT_NOT_REACHED)
       return NotOK; /* this is not really needed, but is here to be defensive */
    #pragma error_messages (on,E_STATEMENT_NOT_REACHED)
    }
    
    /*
     * Function list_q
     * 
     * Implementation of this function is optional but highly 
     * recommended
     */
    
    void
    list_q (void)
    {
       PCB_entry *next;
    
       next = ready_q;
    
       fprintf (stderr, "\n current state of the ready queue\n");
    
       next = ready_q;
       while (next != NULL)
         {              /* traverse to the end of the list */
        fprintf (stderr, "%d\t", next->pid);
        next = next->f_link;
         }
       fprintf (stderr, "\n\n");
    }
    
    
    /*
     * Function re_insert: priority
     * 
     * a function to insert a process back into the queue
     * following a run on the CPU. Depending on the
     * scheduling algorithm chosen this would need to
     * do a lot more. In a priority algorithm with boost
     * and reduction, it would need to look at the
     * percentage of the quantum that the process used
     * and determine if a change to the priority was
     * required. Also, in implementing a mulitlevel
     * priority scheme, a variation of the ready_q
     * pointer would be required. The simplest method
     * would be an array of pointers with one element
     * for each priority level.
     *
     * Not that, in this case it is identical to the
     * insert_new code
     */
    int
    re_insert (PCB_entry * proc, int run_time)
    {
        insert_new(proc);
    }
    
    
    /*
     * Function init_q: FCFS priority
     * 
     * Initialises the ready queue
     * 
     * Written as a function so that, if the ready_q
     * becomes an array of pointers, the initialisation
     * can be changed without re-building the main part
     * of the simulator
     */
    
    int
    init_q (void)
    {
       ready_q = NULL;
        ready_q_tail = NULL;    
       return OK;
    }
    
    
    
    /*
     * function end_run () 
     * Insert code to do any end of processing tasks for the
     * functions written by the student
     */
    int end_run(void)
    {
       fprintf(stderr, "This run had %d concurrent processes\n", Get_num_concurrent());
       return 0;
    }
    

    更新:

    认为 我已经把这个问题隔离开来了:

    if (best_proc->f_link != NULL) {
    

    另外,为了清楚起见,我不相信这是一个多线程应用程序(虽然我是一个完全的noob,所以谁知道呢)-我不知道我可以有一个调试器或堆栈跟踪(从第一版K&R“C编程语言”)所以我也没有这些。(顺便说一句,用C语言编程通常感觉像是一个胖日本男人在打你的脸吗?)

    2 回复  |  直到 14 年前
        1
  •  3
  •   gablin    14 年前

    在我看来没问题-在代码中找不到任何错误。

    它是立即失效,还是在运行一段时间后失效?你确定 init_q 函数在开始使用队列之前实际运行?你试过检查一下 NULL new_insert re_insert 功能?

    顺便说一下,这个程序不是在多线程模式下运行的,对吧?如果需要,您需要在关键部分保护全局变量。

    编辑4: 现在我想我明白了! ready_q_tail

    这里有一个(希望)修正 schedule_next

    PCB_entry *
    schedule_next (void)
    {
       /* if ready_q is null, there are no processes in the system */
       if (ready_q == NULL)
         {
        return NULL;
         }
       else
         { 
           PCB_entry *next;
           PCB_entry *best_proc;
    
            next = ready_q;
            best_proc = next;
               while (next != NULL)
                 {              /* traverse to the end of the list */
    
                if (next->current_priority current_priority) {
                    best_proc = next;   
                }
                next = next->f_link;
               }
            if (best_proc == NULL) {
                return NULL;
            }
    
            // Remove task from queue
            {
                int procHasNext = best_proc->f_link != NULL;
                int procHasPrev = best_proc->b_link != NULL;
    
                if (!procHasNext && !procHasPrev) {
                    // There's only one task in the queue
                    ready_q = NULL;
                    ready_q_tail = NULL;
                } else {
                    if (procHasNext) {
                        if (procHasPrev) {
                            best_proc->b_link->f_link = best_proc->f_link;
                        } else {
                            // Proc to remove is the first in queue
                            ready_q = best_proc->f_link;
                            ready_q->b_link = NULL;
                        }
                    }
    
                    if (procHasPrev) {
                        if (procHasNext) {
                            best_proc->f_link->b_link = best_proc->b_link;
                        } else {
                            // Proc to remove is last in queue
                            ready_q_tail = best_proc->b_link;
                            ready_q_tail->f_link = NULL;
                        }
                    }
                }
            }
    
            // Ensure that the links in PCB to remove doesn't cause any problems
            best_proc->f_link = NULL;
            best_proc->b_link = NULL;
    
            return best_proc;
    
        }
    }
    
        2
  •  0
  •   ypnos    14 年前

    使用 valgrind