weixin_42207215
weixin_42207215
采纳率25%
2018-11-12 09:29

C++ 多线程同步问题?

#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <mutex>
#include <condition_variable>
#include <map>
#include <ctime>
#include <random>
#include <chrono>
#include <unistd.h>

#define NUM_OF_SAMPLES 50
#define MAX_NUM_OF_THREADS 6

using namespace std;

class Sensor {
private:
    string sensorType;

public:
    Sensor(string& type) : sensorType(type){}

    //Declare a virtual method to be overridden by derived classes:
    virtual double getValue() = 0;

    //Declare non-virtual method:
    string getType() {
        return sensorType;
    }
};

class TempSensor : public Sensor {
public:
    TempSensor(string& s) : Sensor(s) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 20) + 10;
    }
};

class PressureSensor : public Sensor {
public:
    PressureSensor(string& type) : Sensor(type) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 10) + 95;
    }
};

class CapacitiveSensor : public Sensor {
public:
    CapacitiveSensor(string& type) : Sensor(type) {}

    double getValue() {
        return (double)rand() / ((double)RAND_MAX / 4) + 1;
    }
};

class BC {
private:
    bool lock = false; //'false' means that the BC is not locked
    vector<Sensor *>& theSensors; //reference to vector of Sensor pointers
    mutex BC_mu;
    condition_variable cv;
    map<int, string> sensorMap;
    map<int, int> countMap;

public:
    BC(vector<Sensor *>& sensors) : theSensors(sensors) {
        sensorMap.insert(pair<int, string>(0, "temperature"));
        sensorMap.insert(pair<int, string>(1, "pressure"));
        sensorMap.insert(pair<int, string>(2, "capacitive"));
    }

    void requestBC(int index) {
        unique_lock<mutex> lk(BC_mu);
        if (lock) {
            cout << "BusController is locked, thread " << index << " is about to suspend.." << endl;
            cv.wait(lk);
        }
        lock = true;
        cout << " BusController locked by thread " << index << endl;
        return;
    }

    double getSensorValue(int selector) {
        countMap[selector]++;
        return theSensors[selector]->getValue();
    }

    void releaseBC(int index) {
        unique_lock<mutex> lk(BC_mu);
        lock = false;
        cout << "BusController unlock by thread " << index << endl;
        cv.notify_one();
    }

    string getSensorType(int selector) {
        return sensorMap[selector];
    }

    void printCntSensorType() {
        for (auto it = countMap.begin(); it != countMap.end(); it++) {
            cout << sensorMap[it->first] << " accessed " << it->second << " times" << endl;
        }
    }
};


void run(BC& theBC, int index) {
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis1(0, 2);
    uniform_int_distribution<> dis2(1000, 10000);

    for (int i = 0; i < NUM_OF_SAMPLES; i++) {
        theBC.requestBC(index);
        int sensorTypeIndex = dis1(gen);
        string sensorStr = theBC.getSensorType(sensorTypeIndex);
        double randSensorValue = theBC.getSensorValue(sensorTypeIndex);
        cout << "       sample value from thread " << index << " from " << sensorStr << " sensor = " << randSensorValue << endl;
        theBC.releaseBC(index);
        usleep(dis2(gen));
     }
}

int main() {
    vector<Sensor *> sensors;
    string temp = "temperature", pressure = "pressure", capa = "capacitive";
    sensors.push_back(new TempSensor(temp));
    sensors.push_back(new PressureSensor(pressure));
    sensors.push_back(new CapacitiveSensor(capa));

    BC theBC(ref(sensors));
    thread theThreads[MAX_NUM_OF_THREADS];
    for (int i = 0; i < MAX_NUM_OF_THREADS; i++) {
        theThreads[i] = thread(run, ref(theBC), i);
    }
    for (int i = 0; i < MAX_NUM_OF_THREADS; i++) {
        theThreads[i].join();
    }
    theBC.printCntSensorType();
    return 0;
}

代码如上所示,主要实现的功能是六个线程去抢占BC类,然后选择不同的sensor进行输出,但是BC类中关于线程的同步机制觉得存在问题,求大神指导。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

相关推荐