2013-11-24 22 views
0

我正在用我正在进行的一个项目打墙,并且想知道是否有人可以为我提供一些帮助。我会尽量简化我的代码,以免盯着100多条乱码。我很确定只有第一个代码块是相关的,其他的是我在sys.c中的系统调用以供参考。使用信号灯的阅读器优先顺序

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

一个例子的输出是:

作家0 wrote- 6

写入器1 wrote- 4

器2 wrote- 2

读卡器0读 - 2

和然后它冻结。

从我可以告诉的Critcal部分信号量永远不会被释放。

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

在此先感谢。

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

注: RWwait和RWsignal的包装方法,成功地使系统调用我的信号操作。 csMutex用于控制对临界区域的访问。 nrMutex是读者的队列控制到临界区 两个互斥的值是最初1. *号是号的指针,其中两个读取器和写入访问

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! 

} 

回答

0

我会说你的读者:

 nr++; 

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

是一个竞争条件。

同样地,我也不会做:

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

没有第一个,也不会是那么有可能为读者访问临界区,而读者已经在那里了? 与这些想法是,如果这是第一个阅读器nr == 1,那么它会等待所有的作家完成。然后作家不能访问CS,直到所有读者完成nr == 0. – ReezaCoriza

+0

它是一种竞争条件,因为理论上两个读者都可以执行nr ++;在执行该行之前if(nr == 0) – woolstar

+0

ahhhh!你是对的!关于如何解决这个问题的任何想法?如果我把这些线条拿出来,那么它将摆脱竞争条件,但它会给予读者和作者同等的优先权,不是吗? – ReezaCoriza