#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类中关于线程的同步机制觉得存在问题,求大神指导。