Pthreads:工作线程永远等待来自控制器线程的信号

时间:2018-03-07 18:38:09

标签: c++ linux multithreading data-structures pthreads

我正在进行线程调度分配,它包含一个控制器线程,指示何时允许工作线程("总线")离开其工作站。通常会有很多总线线程通过文本文件传送,这些文本文件可能位于多个站点之一,但是通过创建具有预定义值(id,方向,加载和交叉时间)和单个总线的单个总线可以看出这个问题。我在这里做的工作是为了尽量减少代码。

每个总线线程的一般工作流程如下:

  1. 创建一个包含con_var,lock和flag的结构 (初始化为0)。这将被推送到第一个队列。
  2. 创建一个带有id,direction等的Bus类对象。这将被推送到 第二个队列。两个队列代表同一个站点。
  3. 等待来自控制器的信号开始加载。一旦收到,就睡觉吧 巴士'加载时间。
  4. 在唤醒时,将创建的结构和总线对象推送到其队列
  5. 等待来自控制器的信号......
  6. 最后一部分是问题;虽然我已经验证控制器IS不断发送信号,但线程不会停止等待。它只是永远挂起,永远不会越过。我不确定我是否发送了错误的信号,或者问题是否是其他问题,但我很困惑,并希望得到任何可用的帮助。 前2个代码窗口分别用于控制器和总线功能,这是问题的核心,也是我希望有人愿意看的内容。第三个是我的结构/类的标题,如果需要,final是整个可编译的主函数。

    busController()

    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);
                }
    
        }
    }
    

    busFunction()

    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);
    }
    

    StructClassMCVE.h

    #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
    

    mainMCVE.cpp:

    #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);
        }
    }
    

0 个答案:

没有答案