C 使用信号量的读卡器优先级
我正在做一个项目,我想知道是否有人能为我提供一些帮助。我会尽量简化我的代码,这样你就不会盯着100多行jibberish了。我非常确定,只有第一个代码块是相关的,其他代码块是我在sys.c中的系统调用,以供参考 我应该创建一个程序,用我自己的信号量模拟进程同步的读卡器优先级实现。当我运行它时,每当读卡器到达关键部分时,就会出现死锁。我不知道我做错了什么 一个示例输出是: 写入程序0写入了-6 作家1-4 作家2写道-2 读卡器0已读-2 然后它冻结了 据我所知,Critical部分的信号量永远不会被释放 我相信问题出在我的程序上,而不是我的信号量、等待和信号操作,但我将它们包括在下面以供参考 提前谢谢 我的尝试如下: 我省略了初始化和内存映射,这是基本结构 注: rwait和RWsignal是包装器方法,它们成功地对我的信号量操作进行系统调用。 csMutex用于控制对关键部分的访问。 nrMutex用于控制读卡器到关键部分的队列 两个互斥量值最初都是1。 *number是指向读写器都可以访问的数字的指针C 使用信号量的读卡器优先级,c,synchronization,deadlock,semaphore,C,Synchronization,Deadlock,Semaphore,我正在做一个项目,我想知道是否有人能为我提供一些帮助。我会尽量简化我的代码,这样你就不会盯着100多行jibberish了。我非常确定,只有第一个代码块是相关的,其他代码块是我在sys.c中的系统调用,以供参考 我应该创建一个程序,用我自己的信号量模拟进程同步的读卡器优先级实现。当我运行它时,每当读卡器到达关键部分时,就会出现死锁。我不知道我做错了什么 一个示例输出是: 写入程序0写入了-6 作家1-4 作家2写道-2 读卡器0已读-2 然后它冻结了 据我所知,Critical部分的信号量永远不
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互斥应该实现。