【问题标题】:reader priority using semaphores使用信号量的读者优先级
【发布时间】:2013-12-09 11:19:32
【问题描述】:

我正在做的一个项目遇到了困难,我想知道是否有人可以为我提供一些帮助。我会尽量简化我的代码,这样你就不会盯着 100 多行乱码。我很确定唯一的第一个代码块是相关的,其他的是我在 sys.c 中的系统调用以供参考。

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

一个示例输出是:

作家 0 写了 - 6

作家 1 写了 - 4

作家 2 写了 - 2

阅读器 0 读取 - 2

然后它就冻结了。

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

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

提前致谢。

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

注意事项: RWwait 和 RWsignal 是包装器方法,它们成功地对我的信号量操作进行系统调用。 csMutex 是控制对临界区的访问。 nrMutex 是控制读者到临界区的队列 两个互斥锁值最初都是 1。 *number 是一个指向 number 的指针,reader 和 writer 都可以访问

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!

}

【问题讨论】:

    标签: c synchronization deadlock semaphore


    【解决方案1】:

    我会在你的读者中说:

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

    是一个竞争条件。

    同样我不会这样做:

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

    【讨论】:

    • 如果没有第一个,那么读者是否可以在读者已经在那里时访问关键部分?这些的想法是,如果这是第一个读者 nr==1 那么它将等待所有作者完成。然后在所有读者完成 nr == 0 之前,作者无法访问 CS。
    • 这是一个竞争条件,因为理论上两个读者可以各自执行 nr ++ ;在 if ( nr == 0 ) 之前执行该行
    • 啊啊啊啊!你说得对!关于如何解决这个问题的任何想法?如果我把这些行去掉,那么它将摆脱竞争条件,但它会给读者和作者同等的优先权,不是吗?
    • 优先级完全是另一回事。如果你想让读者共享一个锁,你必须为此创建一个额外的进程安全机制。
    • 这就是 nrMutex 应该实现的目标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 2014-02-20
    相关资源
    最近更新 更多