講解:EEEN30052、C/C++、C/C++、Concurrent SystemsR|C/C++

EEEN30052 Concurrent Systems 2018-19Assignment1. IntroductionThis assignment is concerned with simulating some aspects of a simple embedded computersystem. You may choose between two versions: A1 or A2. Each is worth a different percentageof the overall coursework mark: A1 is a simplified version of the assignment and is worth 50%,while A2 is the full version and is worth 100%.The diagram shown in Figure 1 is a model of a system that is responsible for gatheringenvironmental data from a set of three sensors, each of a different type. In the model a set ofthreads (initially six) are used to gather the data, and then transmit it to a Receiver.Access to the sensors is via a Bus Controller (BC), such that only one thread is granted access ata time. Thus, in order to acquire data, each thread must gain sole access to the BC, configure it tosample from a specific sensor, and sample the data. In order to transmit the data, a thread mustgain access to one of two communications links via a Link Access Controller. Having gainedaccess, it sends its data, and then releases the link. Each thread may use either communicationslink, but once it has gained access to a particular link, no other thread should be allowed to usethat link until it is released.Figure 12If you choose to do A2 you should start by implementing A1, but you will not be required todemonstrate it or upload a copy (of A1). If you choose A1 you do not need to attempt A2, ordemonstrate/upload it. However, in both cases your program should print out messagesclearly indicating the identity of the calling thread and what action it is performing.2. A1 – worth 50% of total coursework marksWrite a C++ program that creates six threads where each thread is identified by an integer and has areference to an object of class BC, which is described below. Each thread executes the following sequence50 times: Request use of the BC by calling the requestBC() method of the BC object. This call attemptsto lock the BC to prevent access by other threads. The thread should print out its identity when thecall is successful. Select a sensor by generating a random number between 0 and 2 inclusive, where 0 represents thetemperature sensor, 1 represents the pressure sensor, and 2 represents the capacitive sensor. Usingthe number generated, request a sample value from the selected sensor by calling the BCsgetSensorValue()method. This returns a double value on the basis of the sensor that wasselected. The thread then obtains the sensor type by, for example, calling the BCsgetSensorType()method. Print out the sensor type and value obtained, together with the threads identity. Increment a counter each time a particular sensor is accessed (there is a different counter for eachsensor type). Call releaseBC() to enable other threads to use the BC, printing out its identity once more. Delay for a random time between 1 and 10 milliseconds.A function called run() is used to implement the above. Objects of class BC have a private booleanmember called lock to help ensure mutually exclusive access to the BC. Hence when a thread wishes toaccess the BC it calls requestBC(), which in turn checks the value of lock. If the BC is not currentlyin use (i.e. lock is false), the thread sets lock to true and the thread will be allowed to proceed to usethe BC. However, if the BC is in use, then the thread calling requestBC() should be suspended until theBC has been relinquished by another thread calling releaseBC(), which in turn sets lock to false.Thus threads are suspended –and resumed- depending on the value of lock.Each sensor is represented by its own class (TempSensor, PressureSensor and CapacitiveSensor), whichare derived from a base abstract class called Sensor. Sensor has one virtual method called getValue(),and one non-virtual method called getType(). Classes derived from Sensor inherit getType(), butmust implement getValue(), otherwise they are also designated abstract (abstract classes cant beinstantiated). Each sensor returns values randomly chosen from within the ranges shown in Table 1.Sensor Range of valuesTempSensor 10-30PressureSensor 95-105CapacitiveSensor 1-5 Table 13The main function instantiates the sensors (it is recommended to use a vector rather than an array for thispurpose), and creates six threads. It also creates one instance of class BC, passing the vector to it byreference. It should initiate execution of the threads and should not terminate until all threads haveterminated. To help you get started the following is a partially-complete skeleton of the program://comment: authors name, ID, and date.//pre-processor directives:#include #include ....using namespace std;//global constants:int const MAX_NUM_OF_THREADS = 6;....//global variables:....//function prototypes: (as required)....class Sensor { //abstract base class that models a sensor public: Sensor(string& type) //constructor : sensorType(type) {} //Declare a virtual method to be overridden by derived classes: virtual double getValue() = 0; //Declare non-virtual method: string getType() { //returns the type of Sensor that this is: .... } //Declare any instance variable(s): ....}; //end abstract class Sensorclass TempSensor : public Sensor { //syntax declares a derived class public: TempSensor (string& s) //constructor : Sensor(s) {} virtual double getValue() { //return a random value of ambient temperature between 10 and 30 .... } //end getValue}; //end class TempSensorcontinued..4class PressureSensor : public Sensor {........}; //end class PressureSensorclass CapacitiveSensor : public Sensor {........}; //end class CapacitiveSensorclass BC {public://constructor: initialises a vector of Sensor pointers that are//passed in by reference:BC(std::vector& sensors) : theSensors(sensors) {}void requestBC() {....}double getSensorValue(int selector) {return (*theSensors[selector]).getValue();}string getSensorType(int selector) {....}void releaseBC() {....}private:bool lock = false; //false means that the BC is not lockedstd::vector& theSensors; //reference to vector of Sensor pointers std::mutex BC_mu; //mutex ....}; //end class BC//run function –executed by each thread:void run(BC& theBC, int idx) {.... for (i=0; i // request use of the BC: ....// generate a random value between 0 and 2, and use it to// select a sensor and obtain a value and the sensors type: ....// increment counter for sensor chosen (to keep count of// how many times each was used)5continued..// release the BC: ....// delay for random period between 0.001s – 0.01s: .... }}int main() { //declare a vector of Sensor pointers: std::vector sensors; //initialise each sensor and insert into the vector: string s = temperature sensor; sensors.push_back(new TempSensor(s)); //push_back is a vector method. .... // Instantiate the BC:BC theBC(std::ref(sensors)); //instantiate and start the threads: std::thread the_threads[MAX_NUM_OF_THREADS]; //array of threads for (int i = 0; i //launch the threads: .... } //wait for the threads to finish: .... cout //print out the number of times each sensor was accessed: .... return 0;}The code is incomplete in a number of different senses, and you must modify it in order to complete A1.You are free to include any additional methods/functions/variables/constants, as you think necessary. Noteon commenting: a solution that is poorly commented will lose up to 5% of the total marks, and one thatdoes not calculate the delay period correctly will also lose up to 5%.Part of an example output is shown below:6Notes on the Program2.1 Thread IdentityObtaining the id value of a thread in C++11 is done withstd::this_thread::get_id()-however this returns an object not an integer, and although this can be passed to coutfor printing (e.g. cout simple way to cast it to an int.For example, if you create say, three threads, and printed out their ids, you might get234Ideally, we want to be able to associate a known integer id with each thread so we can identify them asthread 0, thread 1, etc..One solution is to create a std::map of thread ids v. integers, e.g.thread id int value 2 0 3 1 4 2..etc.To associate the thread id with an integer value in a map, the following might be helpful: std::mutex mu; //declare a mutex std::unique_lock map_locker(mu); //lock the map via the mutex. //insert the threadID and id into the map: threadIDs.insert(std::make_pair(std::this_thread::get_id(), id)); map_locker.unlock(); //were done, unlock the map.Such code need only be executed once, and could for example, be added to the run function that eachthread executes. 7A recommended way to search the map by thread id is to use an iterator, e.g.: std::map ::iterator it = threadIDs.find(std::this_thread::get_id()); if (it == threadIDs.end()) return -1; //thread id NOT found else return it->second; //thread id found, return the //associated integer –note the syntax.It might be useful to put the search code in a separate function.You will need the following preprocessor directive in order to use a map: #include For more info about maps, with more examples, see for example:http://thispointer.com/stdmap-tutorial-part-1-usage-detail-with-examples/2.2 Creating a delay by generating random values.One way to generate say, random integers, is to use a pseudo-random number generator (prng), and seedit with a value. The code below shows one way of doing this (adapted fromhttp://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution)std::mt19937 gen(time(0)); //A prng seeded by time(0). //time(0) gives the number of seconds elapsed since the start//of the world according to Unix (00:00:00 on 1st January 1970).std::uniform_int_distribution dis(1, 1000); //set up the distribution //from which integers will be drawn.int n = dis(gen); //generate a pseudo-random integer between 1-1000.-the pseudo-random number is stored in n.You will need the following preprocessor directives in order to use the above example code:#include #include Note that only a single generator is necessary, which only needs to be initialised once. Furthermore, asolution that does not calculate the delay period correctly will lose up to 5% of the total marks.2.3 Vectors or Arrays?A vector and an array are similar in that they both contain a list of data, however the basic difference isthat the size of an array is fixed, whereas a vector grows automatically as more items are added to it.Further代寫EEEN30052作業(yè)、代寫C/C++語言作業(yè)、C/C++程序作業(yè)代做、代做Concurrent Systems作業(yè)more, the availability of methods associated with vectors make them very flexible.In general in C++11 it is straightforward to create arrays of objects of classes from the standard library,such as std::thread, for example. However, arrays of objects of user-defined classes, such asSensor, or Link, are more awkward to use. For such user-defined classes you may findstd::vector much easier to handle, for example:std::vector sensors; //vector of pointers to Sensor objectsor std::vector commsLinks; //vector of Link objectsA example tutorial is:http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-tostdvector-Part-1.htm82.4 InheritanceIn C++ one class (the base class) can define methods and variables/constants (i.e. class members) whichcan be inherited by another (derived class). In principle this means that such methods/variables/constantsneed to be defined only once (thereby promoting re-useability) yet can be used by instances of both baseand derived classes. In the following example, B declares its own members, in addition to those inheritedfrom A:#include using namespace std;class A{ //base class public: A (int i) //constructor : x(i) { } //initialise private instance variable x void set_x (int a) { x = a; } //set value of x int get_x ( ) { return x; } private: int x; //instance variable}; //end class Aclass B : public A { //derived class public: B (int i, int j) //constructor must call As constructor : A(i) {p = j;} //initialise private instance variable p void set_p(int a) { p = a; } //set value of p int get_p( ) { return p; } private: int p; //instance variable}; //end class B//The following illustrates use:int main() { A a(3); //create instance of A, initialise member variable//x to 3 a.set_x(4); //change x to new valuecout B b(5,4); //create instance of B and initialise member //variables x to 5 and p to 4 b.set_x(6);//use b uses inherited method to set new value of xcout cout }prints out464If a class contains one or more methods that are declared virtual then the class is said to be abstract andcant be instantiated; however any derived classes from which instances are required are then obliged todefine the method. This is useful if, for some reason it didnt make sense to define the method in the baseclass, yet you still wanted derived classes to have it, but define it in different ways. Using the above as anexample, if in class A we had declared set_x() as a virtual method, i.e. virtual void set_x (int a) = 0;//syntax specifies method as virtualthen any attempt to instantiate A now fails:9 A a(3); //FAILS –cant make an instance of abstract class ABecause B doesnt implement set_x() the following also fails to compile: B b(5,4); //FAILS –cant make an instance of BIn order for this statement to compile, B must implement set_x(), for example by writing void set_x (int a) { x = a; } //set value of xInheritance is a feature of object-oriented software design that permits the use of powerful techniques,such as polymorphism. The following link provides more information:http://www.cplusplus.com/doc/tutorial/inheritance/3. A2 – worth 100% of total coursework marksIn A1 we were concerned with creating threads and being able to lock access to the Bus Controller. In thisversion we extend the solution to include access to the communications links. In particular, the threadsshould request a Link from a LinkAccessController object. When one is available, the samplevalues that the thread has acquired can be transmitted. The Link object is used to copy this data to theReceiver object. To facilitate this, each thread stores sensor data in objects of a class calledSensorData, which stores the samples internally in a vector.The main program should create and initiate all the threads, and should wait until they have all haveterminated before calling the Receiver’s method that prints out all the sensor data.Part A2 builds on A1 and requires the following additional classes:SensorData. As indicated above, data sampled by each thread is stored in a vector managed byinstances of this class. Once started, each thread would create three instances, one for each sensor type.When a sample is received from the Bus Controller its type is checked, and then stored in the appropriateSensorData object. Later, when the time comes to transmit the data, these objects are sent to theReceiver via a link. The partial code for SensorData is given below:class SensorData { //Utility class to store sensor data public: SensorData(string type) //Constructor : sensor_type(type) {} string getSensorType() {return sensor_type;} std::vector getSensorData() {return sensor_data;} void addData(double newData) {....} private: .... std::vector sensor_data;}; //end class SensorDataLinkAccessController. As indicated above, there are two communications links that can beaccessed simultaneously. The actual number is defined by a global constant:int const NUM_OF_LINKS = 2; 10A single instance of the LinkAccessController class, called lac, controls access to these links,ensuring that they can be used simultaneously. However, if all the links are in use and additional threadsattempt to gain access to one, these latter threads should be suspended until one or more links becomeavailable. Threads should print out their identity, together with their actions, when accessing links: i.e.when they successfully acquire and release a link, and when (if) they are suspended. The partial code forLinkAccessController is given below.class LinkAccessController { public: LinkAccessController(Receiver& r) //Constructor : myReceiver(r), numOfAvailableLinks(NUM_OF_LINKS) { for (int i = 0; i commsLinks.push_back(Link(myReceiver, i)); } } //Request a comms link: returns a reference to an available Link. //If none are available, the calling thread is suspended. Link& requestLink() { .... return std::ref(commsLinks[linkNum]); } //Release a comms link: void releaseLink(Link& releasedLink) { .... } private: Receiver& myReceiver; //Receiver reference int numOfAvailableLinks; std::vector commsLinks; std::mutex LAC_mu; //mutex....}; //end class LinkAccessControllerLink. Instances of this class represent the communication links in the system. The partial code for Linkclass is given below:class Link { public: Link (Receiver& r, int linkNum) //Constructor : inUse(false), myReceiver(r), linkId(linkNum) {} //check if the link is currently in use bool isInUse() { return inUse; } //set the link status to busy void setInUse() { inUse = true; } continued..11 //set the link status to idle void setIdle() { inUse = false; } //write data to the receiver void writeToDataLink(SensorData sd) { ....} //returns the link Id int getLinkId() { return linkId; } private: bool inUse; Receiver& myReceiver; //Receiver reference int linkId;}; //end class LinkReceiver. An instance of this class called theReceiver receives the sensor data from the Linkobjects via calls to a method called receiveData(), which in turn determines the sensor type andwrites it into the appropriate vector (there is one vector of type double for each sensor type). The partialcode for class Receiver is given below.class Receiver { public: Receiver () { } //constructor //Receives a SensorData object: void receiveData(SensorData sd) { .... } // print out all data for each sensor: void printSensorData () { ....} private://mutex:.... //vectors to store sensor numeric data received from threads:std::vector temp_data;....}; //end class Receiverrun function.The run function for each thread should be extended. The following steps should be added to thesequence given in version A1:For each sensor type request access to a link; the thread should print out its identity and transmit the data for that sensor type to the Receiver; release the link, printing out its identity once more; once a link has been released, delay for a random time between 1 and 10 milliseconds.12A link can be conveniently obtained using a pointer as follows:Link* link = &lac.requestLink();and used to send data to the Receiver with: link-> writeToDataLink(...); //note pointer syntaxA link can be released with: lac.releaseLink(*link);main function.The main function creates the following objects/data structures: theBC, sensors and the_threads-as developed in part A1 of this assignment. lac-an object of class LinkAccessController. theReceiver-an object of class Receiver.int main() { //declare and initialise a vector of pointers to Sensors:std::vector sensors;string s = temperature sensor;sensors.push_back(new TempSensor(s)); //push_back is a vector method. .... // Instantiate the BC:BC theBC(std::ref(sensors)); // Instantiate the Receiver: .... // Instantiate the LinkAccessController: .... //instantiate and start the threads: std::thread the_threads[MAX_NUM_OF_THREADS]; //array of threads for (int i = 0; i //launch the threads: .... } //wait for the threads to finish: .... // Print out all the data in the Receiver: .... cout return 0;}Notes on the ProgramAs per A1, a solution that is poorly commented will lose up to 5% of the total marks, and one that doesnot calculate the delay period correctly will also lose up to 5%. You are also expected to use the globalconstants defined in the program in a consistent way throughout.134. Laboratory ArrangementsYour solution to the assignment (A1 or A2) will be demonstrated in Barnes Wallis on your final allocatedlab for Concurrent Systems (please check your timetable for the actual date). Demonstration of yourprogram at other times is not permitted. You will be expected to upload a copy of the program toBlackboard for marking during the demonstration.NOTE CAREFULLY: a learning objective of this assignment is to be able toexplain how a concurrent program works. During the demonstration you willbe asked simple questions about your program, for example the effect on theprogram of changing one or more of the constants or variables. Marks will bededucted if you cannot answer the questions that you are asked.5. DeliverablesAn electronic copy of your program should be uploaded at the end of the final session. Programs withoutcomments or with few comments will automatically receive low marks.6. PlagiarismThis is an individual assignment. Any plagiarism will be referred to the Director of Studies and penaltieswill be applied in accordance with University policy.轉(zhuǎn)自:http://ass.3daixie.com/2018111154047171.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,870評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,742評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,527評論 6 407
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,010評論 1 322
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,250評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,656評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,853評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,103評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,472評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,717評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,487評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,815評論 2 372

推薦閱讀更多精彩內(nèi)容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,715評論 0 3
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,479評論 0 13
  • 志理高中看卷很快,第三天所有成績就都排好了。 看到成績單安憶然突然說了一句,“不是吧,樂煙,你怎么分書都是單位數(shù),...
    星辰star2020閱讀 212評論 0 2
  • 不要把知識與智慧混淆,知識是告訴你怎樣生存,智慧則告訴你如何生活。
    圈圈18閱讀 202評論 0 2
  • 1.感恩今天下好大雨,讓天氣特別涼爽。 2.感恩辦公室的同事請產(chǎn)假了,讓我可以搬到她的位置坐。 3.感恩同事幫我拿...
    憶秦YQ閱讀 172評論 0 0