【发布时间】: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