读者优先使用信号量

时间:2013-11-24 21:13:43

标签: c synchronization deadlock semaphore

我正在与我正在进行的项目碰壁,我想知道是否有人可以给我一些帮助。我会尝试简化我的代码,这样你就不会盯着100多行乱码。我很确定唯一的第一个代码块是相关的,其他代码是我在sys.c中的系统调用以供参考。

我应该创建一个程序来模拟使用我自己的信号量的进程同步的读者优先级实现。当我运行它时,只要读者进入关键部分,我就会陷入僵局。我不知道我做错了什么。

示例输出是:

作家0写道 - 6

作家1写道 - 4

作家2写了 - 2

读者0阅读 - 2

然后冻结。

据我所知,Critcal Section信号量永远不会被释放。

我认为问题在于我的程序,而不是我的信号量,等待和信号操作,但我将它们包含在下面以供参考。

提前致谢。

到目前为止,我的尝试如下: 我遗漏了我的初始化和内存映射,这是基本结构

注意: RWwait和RWsignal是包装器方法,它成功地对我的信号量操作进行系统调用。 csMutex用于控制对关键部分的访问。 nrMutex是将读者队列控制到关键部分 两个互斥锁值最初都是1。 * number是指向读者和作者可以访问的数字的指针

int i;
//create writers
for(i=0; i < writers; i++){
    if (fork()==0){
        while(1){
            RWwait(csMutex);    //wait for the critical section and lock
            *number = rand() % 10;
            printf("Writer %d wrote- %d\n", i, *number);
            RWsignal(csMutex);//unlock critical section
        }
    }
}

int nr = 0;     //number of readers
//create readers
for(i=0; i < readers; i++){
    if (fork()==0){
            while(1){
            RWwait(nrMutex);
            nr++;

            if (nr == 1) 
                RWwait(csMutex);
            RWsignal(nrMutex);

            printf("Reader %d read- %d\n", i, *number);

            RWwait(nrMutex);
            nr--;
            if (nr == 0)
            RWsignal(csMutex);
                RWsignal(nrMutex);
        }
    }
}

这些是我在sys.c中的系统调用和结构 再次,仅供参考

struct ProcQ {
    struct task_struct *ts;
    struct ProcQ *next;

};

struct RW_Sem {
    int value;
    char *type;
    //Front and back nodes for the queue
    struct ProcQ *front;
    struct ProcQ *back;
};

等待操作:

asmlinkage long sys_RW_wait(struct RW_Sem *sem){
spin_lock(&sem_lock);   //locks the program
sem->value -= 1;    //decrement value

if (sem->value < 0){            //insert into queue
    struct ProcQ *node; //create a new node for the queue
    node = (struct ProcQ*)kmalloc(sizeof(struct ProcQ), GFP_KERNEL);
    node->ts = current; //assign this process to task_struct
    node->next = NULL;  //assign the next node to null

    if(sem->front == NULL){ //if the process queue is empty
        sem->front = node;
        sem->back = node;
    }

    else{   //if the queue is NOT empty
        sem->back->next = node;
        sem->back = node;       
    }
    set_current_state(TASK_INTERRUPTIBLE);  //sleep my child
    spin_unlock(&sem_lock);         //unlock
    schedule();
}

else{                   //queue bypass
    spin_unlock(&sem_lock);
}
return 0;
}

信号操作:

asmlinkage long sys_RW_signal(struct RW_Sem *sem){
spin_lock(&sem_lock);   //locks the program
sem->value += 1;        //increment value


if(sem->value <= 0){                     //wake up process, otherwise bypass
    struct ProcQ *dqProc;            //temporary node pointer for signaled process
    struct task_struct *wake;        //temp for task struct to wake
    dqProc = sem->front;

    if (dqProc != NULL) {          
        wake = dqProc->ts;
        if(sem->front==sem->back){      //if only item in queue
            sem->front = NULL;
            sem->back = NULL;   
        }

        else{
                sem->front = dqProc->next;
        }

        wake_up_process(wake);  //wake up!
        kfree(dqProc);                  //free that space
    }

}

spin_unlock(&sem_lock); //unlock
return 0;       //success!

}

1 个答案:

答案 0 :(得分:0)

我会在读者中说:

        nr++;

        if (nr == 1) 
            RWwait(csMutex);

是竞争条件。

同样我也不会这样做:

        if (nr == 0)
        RWsignal(csMutex);