我正在进行线程调度分配,它包含一个控制器线程,指示何时允许工作线程("总线")离开其工作站。通常会有很多总线线程通过文本文件传送,这些文本文件可能位于多个站点之一,但是通过创建具有预定义值(id,方向,加载和交叉时间)和单个总线的单个总线可以看出这个问题。我在这里做的工作是为了尽量减少代码。
每个总线线程的一般工作流程如下:
最后一部分是问题;虽然我已经验证控制器IS不断发送信号,但线程不会停止等待。它只是永远挂起,永远不会越过。我不确定我是否发送了错误的信号,或者问题是否是其他问题,但我很困惑,并希望得到任何可用的帮助。 前2个代码窗口分别用于控制器和总线功能,这是问题的核心,也是我希望有人愿意看的内容。第三个是我的结构/类的标题,如果需要,final是整个可编译的主函数。
void *busController (void* n){
pthread_mutex_lock(&load_lock);
int remainingBuss = totalBusCount;
readyToLoad = true;
pthread_cond_broadcast(&loadReady_cond);
pthread_mutex_unlock(&load_lock);
while (true){
//if there's a single bus in all queues (the first of several scenarios to come)
if(loadedBusCount == 1){
pthread_mutex_lock(&SouthCondition.front().lock_var);
SouthCondition.front().flag = 1;
pthread_cond_signal(&SouthCondition.front().cond_var);
//NOTE: printing &SouthCondition.front().cond_var shows different address than bus thread is waiting for
pthread_mutex_unlock(&SouthCondition.front().lock_var);
}
}
}
void *busFunction (void* t){
CondStruct condition; //Will be pushed to the first queue, contains cond_var, lock, and condition flag for the bus
pthread_mutex_init(&condition.lock_var, NULL);
pthread_cond_init(&condition.cond_var, NULL);
condition.flag = 0;
struct BusStructure *data = (struct BusStructure *) t;
//create Bus object which takes its data from the bus structure for easy access inside queue
Bus bus(((BusStructure*)t)->dir, ((BusStructure*)t)->id, ((BusStructure*)t)->loadTime,
((BusStructure*)t)->crossTime);
//wait for signal to begin loading from controller thread
pthread_mutex_lock (&load_lock);
while(readyToLoad == false){
pthread_cond_wait(&loadReady_cond, &load_lock);
}
cout << "BUS HAS BEEN UNLOCKED AND CAN PROCEED TO START LOADING" <<endl;
pthread_mutex_unlock (&load_lock);
usleep((((BusStructure*)t)->loadTime)*1000000); //sleep to simulate load time
//Bus has now loaded, add to relevant queue
pthread_mutex_lock(&busLoading_lock);
cout << "Pushing bus " <<bus.getID()<<" to queue"<<endl;
pthread_mutex_lock(&busToQueue_lock);
SouthCondition.push(condition);
SouthBus.push(bus);
pthread_mutex_unlock(&busToQueue_lock);
loadedBusCount++;
pthread_mutex_unlock(&busLoading_lock);
//Wait for crossing signal from controller (THIS IS THE PROBLEM AREA, BUS WAITS FOREVER)
pthread_mutex_lock(&condition.lock_var);
while(condition.flag == 0){
cout <<"Thread "<<bus.getID()<<" is now waiting for " << &condition.cond_var << endl;
pthread_cond_wait(&condition.cond_var, &condition.lock_var);
}
cout <<"TIME TO CROSS, WHICH ISN'T IMPLEMENTED YET. THIS PRINTOUT IS THE SUCCESS." <<endl;
pthread_mutex_unlock(&condition.lock_var);
}
#ifndef StructClassMCVE_H
#define StructClassMCVE_H
struct BusStructure{
public:
char dir;
int id;
double loadTime;
double crossTime;
};
class Bus{
public:
char dir;
int id;
double loadTime;
double crossTime;
Bus(char d, int i, double l, double c){
dir = d;
id = i;
loadTime = l;
crossTime = c;
}
~Bus(){}
char getDirection(){return dir;}
int getID(){return id;}
double getLoadingTime(){return loadTime;}
double getCrossingTime(){return crossTime;}
};
struct CondStruct{
pthread_cond_t cond_var;
pthread_mutex_t lock_var;
int flag;
};
#endif
#include <iostream>
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#include<cstring>
#include<sstream>
#include<cstdlib>
#include<queue>
#include<math.h>
#include<time.h>
#include <unistd.h>
#include<pthread.h>
#include<ctype.h>
#include <vector>
#include <sys/wait.h>
#include <fstream>
#include<ctype.h>
#include"StructClassMCVE.h"
using namespace std;
int totalBusCount;
int loadedBusCount = 0;
pthread_cond_t loadReady_cond;
bool readyToLoad = false;
pthread_mutex_t load_lock;
pthread_mutex_t busLoading_lock;
pthread_mutex_t busToQueue_lock;
queue<CondStruct> SouthCondition;
queue<Bus> SouthBus;
void *busFunction (void* t){
CondStruct condition; //Will be pushed to the first queue, contains cond_var, lock, and condition flag for the bus
pthread_mutex_init(&condition.lock_var, NULL);
pthread_cond_init(&condition.cond_var, NULL);
condition.flag = 0;
struct BusStructure *data = (struct BusStructure *) t;
//create Bus object which takes its data from the bus structure for easy access inside queue
Bus bus(((BusStructure*)t)->dir, ((BusStructure*)t)->id, ((BusStructure*)t)->loadTime,
((BusStructure*)t)->crossTime);
//wait for signal to begin loading from controller thread
pthread_mutex_lock (&load_lock);
while(readyToLoad == false){
pthread_cond_wait(&loadReady_cond, &load_lock);
}
cout << "BUS HAS BEEN UNLOCKED AND CAN PROCEED TO START LOADING" <<endl;
pthread_mutex_unlock (&load_lock);
usleep((((BusStructure*)t)->loadTime)*1000000); //sleep to simulate load time
//Bus has now loaded, add to relevant queue
pthread_mutex_lock(&busLoading_lock);
cout << "Pushing bus " <<bus.getID()<<" to queue"<<endl;
pthread_mutex_lock(&busToQueue_lock);
SouthCondition.push(condition);
SouthBus.push(bus);
pthread_mutex_unlock(&busToQueue_lock);
loadedBusCount++;
pthread_mutex_unlock(&busLoading_lock);
//Wait for crossing signal from controller (THIS IS THE PROBLEM AREA, BUS WAITS FOREVER)
pthread_mutex_lock(&condition.lock_var);
while(condition.flag == 0){
cout <<"Thread "<<bus.getID()<<" is now waiting for " << &condition.cond_var << endl;
pthread_cond_wait(&condition.cond_var, &condition.lock_var);
}
cout <<"TIME TO CROSS, WHICH ISN'T IMPLEMENTED YET. THIS PRINTOUT IS THE SUCCESS." <<endl;
pthread_mutex_unlock(&condition.lock_var);
}
void *busController (void* n){
pthread_mutex_lock(&load_lock);
int remainingBuss = totalBusCount;
readyToLoad = true;
pthread_cond_broadcast(&loadReady_cond);
pthread_mutex_unlock(&load_lock);
while (true){
//if there's a single bus in all queues (the first of several scenarios to come)
if(loadedBusCount == 1){
pthread_mutex_lock(&SouthCondition.front().lock_var);
SouthCondition.front().flag = 1;
pthread_cond_signal(&SouthCondition.front().cond_var);
//NOTE: printing &SouthCondition.front().cond_var shows different address than bus thread is waiting for
pthread_mutex_unlock(&SouthCondition.front().lock_var);
}
}
}
int main(int argc, char **argv){
totalBusCount = 1;
pthread_t thread[2];
//create bus thread
struct BusStructure *busEntry = new struct BusStructure;
busEntry -> id = 0;
busEntry -> dir = 'S';
busEntry -> loadTime = 0.6;
busEntry -> crossTime = 1.2;
pthread_create(&thread[0], NULL, busFunction,(void *) busEntry);
//create controller thread
pthread_create(&thread[1], NULL, busController,NULL);
for(int i = 0; i < 2; i++){
pthread_join(thread[i], NULL);
}
}