Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用信号量的读卡器优先级_C_Synchronization_Deadlock_Semaphore - Fatal编程技术网

C 使用信号量的读卡器优先级

C 使用信号量的读卡器优先级,c,synchronization,deadlock,semaphore,C,Synchronization,Deadlock,Semaphore,我正在做一个项目,我想知道是否有人能为我提供一些帮助。我会尽量简化我的代码,这样你就不会盯着100多行jibberish了。我非常确定,只有第一个代码块是相关的,其他代码块是我在sys.c中的系统调用,以供参考 我应该创建一个程序,用我自己的信号量模拟进程同步的读卡器优先级实现。当我运行它时,每当读卡器到达关键部分时,就会出现死锁。我不知道我做错了什么 一个示例输出是: 写入程序0写入了-6 作家1-4 作家2写道-2 读卡器0已读-2 然后它冻结了 据我所知,Critical部分的信号量永远不

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

我应该创建一个程序,用我自己的信号量模拟进程同步的读卡器优先级实现。当我运行它时,每当读卡器到达关键部分时,就会出现死锁。我不知道我做错了什么

一个示例输出是:

写入程序0写入了-6

作家1-4

作家2写道-2

读卡器0已读-2

然后它冻结了

据我所知,Critical部分的信号量永远不会被释放

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

提前谢谢

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

注: rwait和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);
        }
    }
}

等待操作:

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!

}
asm链接长系统等待时间(struct RW\u Sem*Sem){
spin_lock(&sem_lock);//锁定程序
sem->value-=1;//减量值
如果(sem->value<0){//插入队列
struct ProcQ*node;//为队列创建新节点
node=(struct ProcQ*)kmalloc(sizeof(struct ProcQ),GFP_内核);
node->ts=current;//将此进程分配给任务结构
node->next=NULL;//将下一个节点分配给NULL
如果(sem->front==NULL){//如果进程队列为空
sem->front=节点;
sem->back=节点;
}
else{//如果队列不是空的
sem->back->next=节点;
sem->back=节点;
}
设置当前状态(任务可中断);//睡眠我的孩子
旋转解锁(&sem_lock);//解锁
附表();
}
else{//队列旁路
旋转解锁(和扫描锁定);
}
返回0;
}
信号操作:

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!

}
ASM链接长系统RW信号(结构RW\U Sem*Sem){
spin_lock(&sem_lock);//锁定程序
sem->value+=1;//增量值
if(sem->value front;
如果(dqProc!=NULL){
唤醒=dqProc->ts;
if(sem->front==sem->back){//if队列中只有项目
sem->front=NULL;
sem->back=NULL;
}
否则{
sem->front=dqProc->next;
}
唤醒过程(唤醒);//唤醒!
kfree(dqProc);//释放该空间
}
}
旋转解锁(&sem_lock);//解锁
返回0;//成功!
}

我想对你的读者说:

        nr++;

        if (nr == 1) 
            RWwait(csMutex);
这是一个比赛条件

同样,我也不会:

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

如果没有第一个读卡器,那么当读卡器已经在读卡器中时,读卡器不可能访问关键部分吗?其想法是,如果这是第一个读卡器nr==1,那么它将等待所有读卡器完成。然后,在所有读卡器完成nr==0之前,写卡器无法访问CS。这是一个竞争条件,因为实际上,两个读卡器可以分别执行nr++;在其中一个执行行if(nr==0)之前啊哈!你说得对!我有什么想法吗?如果我去掉这些行,它会消除竞争条件,但它会给读者和作者同等的优先级,不是吗?优先级完全是另一回事。如果你想让读者共享一个锁,你必须为此创建一个额外的进程安全机制。这就是nre互斥应该实现。