我很难准确理解我做错了什么。
我有一个用C编写的程序,它从多个线程向队列添加元素。从我的调试中,我可以看到互斥锁按预期工作,但每次工作线程向链表中添加一个元素时,下一个线程就会丢失它。
例如,如果线程1首先进入,那么队列将在插槽0中具有元素1。接下来,线程2进入并附加它自己,这是正确的(在方法返回之前打印出数组的内容将使线程1和2都在队列中(。然而,下次线程调用pushToQueue时,队列内部将只有一个元素(原始元素(,并且它将把自己附加到它认为是数组中唯一的元素上
这是我的简化代码,函数schedule((由另一个类中的线程调用:
//Global Variables
struct node* readyQueue = NULL;
pthread_mutex_t readyLock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t computeReadyCond = PTHREAD_COND_INITIALIZER;
void pushToQueue(struct node* inthread) {
struct node* cur = inthread;
pthread_mutex_lock(&readyLock);
if (findInReadyQueue(cur->tid) != NULL) {
pthread_mutex_unlock(&readyLock);
return;
}
if (readyQueue == NULL) {
// No list exists, so we must create it.
readyQueue = cur;
readyQueue->next = NULL;
readyQueue->prev = NULL;
}
else {
// append the current thread to the end
struct node* tmp = readyQueue;
struct node* prev = NULL;
while (tmp != NULL) {
prev = tmp;
tmp = tmp->next;
}
prev->next = cur;
cur->next = NULL;
}
pthread_cond_signal(&computeReadyCond); //Signal other threads that the queue is ready
pthread_mutex_unlock(&readyLock);
}
//Calling method (called from a pthread in another class)
int schedule(float currentTime, int tid, int remainingTime, int tprio) {
// update global time
global_currentTime = currentTime;
// create a new structure for this thread to put in the queue
struct node curThread;
curThread.tid = tid;
curThread.remainingTime = remainingTime;
curThread.tprio = tprio;
curThread.calledAt = currentTime;
curThread.state = NEW;
if (curThread.remainingTime <= 0) {
removeFromQueue(tid);
return global_currentTime;
}
// push the thread to its queue based on scheduler rules
pushToQueue(&curThread);
waitForCompute(tid);
printf("wait thread has joined from thread %dn", tid);
return global_currentTime;
}
void waitForCompute(int input) {
int tid = input;
pthread_mutex_lock(&readyLock);
while (readyQueue->tid != tid) {
pthread_cond_wait(&computeReadyCond, &readyLock);
}
pthread_mutex_unlock(&readyLock);
}
提前感谢的任何帮助
您将本地变量的地址从schedule
传递给pushToQueue
,这是不应该的。
int schedule(float currentTime, int tid, int remainingTime, int tprio) {
// ...
// create a new structure for this thread to put in the queue
struct node curThread;
// ...
pushToQueue(&curThread);
当schedule
返回时,该内存区域被解除分配。在pushToQueue
方法中,您将全局变量struct node* readyQueue
设置为此内存地址,并将项添加到readyQueue,但redyQueue
指向堆栈上的变量,当函数返回时,该变量将被丢弃。在schedule
方法中,struct node curThread;
可能总是使用相同的内存地址,因此readyQueue
总是指向一个节点结构,每次调用时间表时都会重新创建该节点结构。