Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

COMP2401 - Assignment #5

(Due:Tuesday, March 28th, 2023 @ 11pm)

In this assignment, you will make a simulator for a Store in which customers get into lineups for a fixed number of cashiers. The customers have carts with store items to be purchased. When a customer gets to the front of the line, he/she unloads the items as if simulating a physical check-out at the cash. One the customer pays, he/she leaves the store and the next customer in line moves up.     Your code will make use of threads for cashiers, for a line-coordinator and displaying the store

information. You will then run separate processes as customers that connect to the line coordinator server so that the customer may get into cashier line-ups.

To begin this assignment, you should download the following files:

· makefile -the file that you will use to compile everything.

· store.h -definitions and structs that will be used throughout your code.

· display.h-a few display definitions that you will use for display.

· storeApp.c-the program that will simulate the store simulator.

· lineCoordinator.c- code for a thread that will handle incoming customer/cashier requests.

· display.c-contains the window/drawing code that you will use to display the store information.

· cashier.c - contains code for a thread that will run a single cashier.

· customer.c-a program that represents a customer process.

· generator.c -a program that will generate 100 random customers.

· stop.c-a program used to shut down the server.

You will generate (and use) 4 executables in this assignment:

1. storeApp - opens a widow to display everything as well as set up the server threads. It is the main program simulator.

2. stop-shuts down the server.

3. customer - runs a process that will simulate a single customer at the store.

4. generator-generates random customers for testing.

When compiling the files, you will need to include the -lpthread and -1x11 libraries.

(but the -1x11 is only needed for the storeApp program since it uses a window and graphics.)

(1) Examine the store.h file. It contains the following definitions and constants that represent the store that we will be testing:


Here is a screenshot of what the storeApp may look like while running. It shows 6 cashiers, each with their own line-ups. For each cashier (shown as a gray circle and large gray rectangle), the total moneyCollected is shown at the top, followed by the itemName  and  itemCost  for  the  item currently  being  scanned  and  then  the itemsTotal for the items that the current customer  is  purchasing.  Customers unloading their items at the cash are shown as green circles. Yellow circles indicate that the customer is  paying and about  to  leave.  Red  circles  indicate  that  a customer  is waiting  in  line. As  the customer  unloads  items,  they  will  appear in  the  cashier  information.  New  customers will appear at the bottom of each of the line-ups as they come in. All the displaying work has been done for you, so you do not need to worry about that.

(2) The storeApp.c file contains the code for the main application. A store has been created and  stored as theFunStore. All 6 cashiers have been initialized properly. You need to add code so that the main function does the following:

· It should spawn a thread to start up a line coordinator. This thread should call the handlelncomingRequests()  function  in  the  lineCoordinator.c  file  and  pass  in  a  pointer  to

theFunStore.

It  should  then  spawn  a  thread  for  each  cashier.  This  thread  should  call  the  runCashier() function in the cashier.c file and pass in a pointer to one of the 6 store cashiers … .

representing the  cashier that this thread  is  running.

It then should spawn a thread to handle the displaying of the store. This thread should call the  showSimulation()  function  in  the  display.c  file  and  pass  in  a  pointer  to  theFunStore.

The code should then wait for the line coordinator thread to complete and it should then

shut down all cashier threads. The line coordinator will shut down any customer processes that are still running (more about this later).

The showSimulation() function (in the display.c file) has been completed for you. You MUST

NOT alter any code in the display.c file.Use the makefile that was given to you to compile

everything. Once you have this step completed, run the storeApp in the background (i.e., use &). Make sure that you see the screen snapshot (on the previous page) appear … showing the store. However, you should see no customers, zeroed-out values at each cashier, and an empty blank

circle at each cash. Once you see this, you can be sure that the display thread is working    properly. Type ps in the terminal window. You should see a processes labelled storeApp.

When you close the window, you should see some XIO error(don't worry about this). After closing

the window, you can type ps again … you should see that the storeApp process is no longer     running. If you ever see that a storeApp process is still running (perhaps from an old test), you should kill this process in the terminal using kill followed by the process id.

(3) The code in the handleIncomingRequests() function (from line Coordinator.c) first starts up a server and then goes online into an infinite loop that repeatedly waits for incoming user requests and handles them. Adjust the code so that it accepts an incoming request on the server socket.   From the resulting client socket … you will need to receive the incoming request data and deal    with it according to the switch statement. The idea is that customers and cashiers will

communicate with this line coordinator to ask for information (i.e., cashiers ask for the next

customer and customers ask for a cashier to go to). When the server receives a SHUT DOWN command, it must cause the server to go off line (gracefully) and shut down. Adjust the code so that just this incoming SHUT DOWN command works.

Write code in the stop.c file so that it attempts to shut down the store by sending the

SHUT DOWN command to the line coordinator. Test your code by running the storeApp in the background and then running the stop program. If all works well, the storeApp window should close and should shut down gracefully. Use ps to make sure that the storeApp process has

indeed shut down properly as well as the stop program. Make sure that you don't have any segmentation faults.

(4) Let's get a customer process up and running. In the main() function of the customer.c file, write  code that reads in the command-line arguments and add items to the customer's cart accordingly. The customer program is run with this format:

./customer 314217331945541523

Each command line parameter MUST be a number from 1 to CATALOG SIZE which represents   the index of an item in the catalog. We will use the term barcode to be this index. So, the above    customer would have 11 items in his/her cart, starting with Friskies Dry Cat Food, Butter, Banana, Large  Eggs,etc.    The amount of spaces between the numbers does not matter.

Therefore, your main() function must read in these numbers and fill up the customer's cart with

the exact items indicated . Note that the cart already has a maximum size, you will just be filling up

the array by setting the barcode, name and price of each item based on the fixed arrays at the bottom of the store.h header file.

The customer then goes into an infinite loop. In that loop, it will first connect to the line coordinator server (code written already for you).You must then prepare and send a message to the line

coordinator with the REQUEST CASHIER command, the number of items in the cart and this

customer's process ID. Note that the process ID is a number from 0 to 65536 … so you will need to break it into two separate bytes before sending (either little endian or big endian format …your choice). The customer should then wait for a response from the line coordinator. The response    will wither be AVAILABLE or NONE AVAILABLE.If it is NONE AVAILABLE,you should just     cause the customer to wait 1 second and then attempt to contact the line coordinator again.(This is the situation in real-life where the lines are full to capacity). If the response was AVAILABLE, then you should receive (as the second byte) the cashier number (from 1 to 6). For now,just

receive in that cashier number and do nothing with it. Then add this line of code to do nothing but wait: while (1)  {         usleep(1000000);  }

Go to the lineCoodinator.c file and add code to handle the REQUEST  CASHIER command that

we just made our customers send. It should read in the number of items and the customer's pid (as was sent from the customer). You should then check all the lineups (the line coordinator

keeps track of these) and find the one with the smallest size (which is a number from 1 to 6). If the smallest lineup is at full capacity (i.e., MAX LINEUP),then there is no space available and a

NONE AVAILABLE response should be sent back to the customer.Otherwise, AVAILABLE

should be sent back to the customer along with the smallest lineup number (i .e ., cashier number)

and the customer should be added to the correct line-coordinator lineup (storing its pid) .

Make sure that your code compiles. Run the storeApp again in the background. Start up a

customer in the background (e.g.,/customer 123).You should see the customer appear in the   first lineup. Start a second customer(e.g.,./customer 567). It should appear in the second lineup.

Run the stop program . Type ps in the terminal window and you should see two customer

processes still running. Use the kill command to remove those processes. Type ps to confirm again that they are no longer running.

(5) We now want the customers to be automatically stopped once the store has been shut down. We   will do this by using the SIGUSR2 process signal. Add code in customer.c so that the customer is able to receive a SIGUSR2 signal and when it does … it exits the program with a value of 1.

In the lineCoordinator.c file, add code so that when the line coordinator shuts down, it signals any customers in lineups to quit as well by using the SIGUSR2 signal.

Test your code by running the storeApp in the background. Then start two customers in the

background as well. Then run stop and make sure that the customers are no longer running (by using ps).

Complete the code in the generator.c file so that it runs exactly 100 customer background (i.e.,

use &) processes . For each customer, it should choose a random number of cart items (i .e ., from

1 to 50) and then choose those items randomly as well. Your entire code should simply run your customer program 100 times with appropriate parameters. At first . to make sure that your

command line arguments were created properly, just print out the commands that you plan to run and don't actually start any processes. Once you believe that your code will work, then you can    fully test it by running the customer processes.

Test your program by starting up the storeApp in the background. Then start up the generator

program in the background . You should start seeing the customers appearing as they get

assigned to the lines in order from left to right until it is full. After the lines are all filled up, wait a few more seconds and then run the stop program.

You will see a lot of lines appearing in the terminal window such as this:

CUSTOMER PROCESS 23430 STOPPING*** CUSTOMER ERROR: Could not connect to Line Coordinator

These are customer processes that the generator is creating that are trying to communicate with

the line coordinator. However, we stopped the program . so they are unable to connect . All is ok

you do not need to do anything with this . It may take a few seconds for all the customer

processes to stop . Just check to make sure that the processes have all stopped by using ps. If

you still see some customer processes wait 10 more seconds or so you should see some

more Customer Process Errors appear. Once they stop, do one final ps to ensure that they are all

stopped. If you have any customer processes running at this point … then you likely did something wrong in your code.

(6) Now we need to get the cashiers to start handling the customers in their lineups. In the

lineCoordinator.c file, add code so that it accepts the NEXT CUSTOMER command from the     cashier. This command byte should be followed by another byte indicating the cashier number. If there are no customers in that cashier's lineup, a NONE AVAILABLE byte should be sent back,  otherwise AVAILABLE should be sent back.

If there was a customer available, that customer should move to the cashier and get ready to

unload his/her items. Set up your code so that a SIGUSR1 signal is sent to the customer to signal him/her to start unloading items to their cashier. Then move all customers in that lineup by one

spot.

In the customer.c class, you already have this infinite loop: while (1){ usleep(1000000);}    Adjust the code so that it doesn't loop forever, but only loops until the SIGUSR1 signal has been received.

In the main while loop of the cashier.c file, add code so that the cashier first connects to the line

coordinator and sends a NEXT CUSTOMER request . It should also send its personal cashier ID

(always a number from 1 to 6) ._It must then receive back 1 byte which is either AVAILABLE or

NONE AVAILABLE. If there are no customers available, the code should wait (i .e ., sleep)for

1/10th of a second and then ask the line coordinator again if there is a customer. The delay

ensures that the CPU time is not used up by the cashier who is not really processing anything … it is simply waiting and doing nothing.

Once an AVAILABLE response is returned from the line coordinator, the cashier should go into a

loop to deal with the customer by accepting an incoming request from the customer through a

client socket . The first byte of the request will always be either NEXT ITEM or READY TO PAY .

If it was a NEXT ITEM request, there should also be a second byte from the request that

indicates the barcode product number (i.e., from 0 to CATALOG SIZE). The cashier should go into SERVING status and process that customer's item by setting the itemName, itemCost and update the itemsTotal so that the display thread can show it.

If it was a READ TO PAY request coming in, the cashier should go into FINISHING status, sleep

for 1 second, add the customer's total cart item cost to the total money collected, reset (i .e ., zero

out) the parameters for the next customer, go into WAITING status and then close the client socket and go back to ask the line coordinator for the next customer.

Go back to the customer.c class. After receiving the signal to unload at the cashier, the customer should connect to the appropriate cashier server and then loop through all his/her cart items …

sending the information as a NEXT ITEM request to the cashier with a 1/10th of second delay after each item. When all items have been sent, a READY TO PAY request should be sent to the cashier and the customer process should exit.

That was a lot of code to write. It is now time to test it.Start the storeApp program in the

background.  Start  the  customer  program  as  follows: ./customer                           123456789

You should see the customer appear very briefly as red, then quick turn green and go to the cashier. The  items descriptions and costs should appear very quickly  in sequence. Then the customer should turn yellow and then disappear after a second or two. The money collected

should appear at the top as $52.93 if you did things correctly. If your customer is not showing the proper colors, then you did not set the status of the  cashier  properly.

Once you believe that your code is working,start three customer processes (with the 9 items) in the background as quickly as you can:

./customer                123456789               &

./customer                123456789               &

./customer                                123456789&

They should all appear and disappear within a few seconds. Run your generator program  in the    background just once and watch as the customer come and go.Once all  100 customers are done, verify that there are none in line nor at the cash and that everything is zero-ed out except the total money collected for each cashier. Run stop and then ps to make sure that the processes have     all  stopped.

IMPORTANT SUBMISSIONINSTRUCTIONS;

Submit the following(DO NOT tar YOUR FILES):

1. A Readme text file containing

·  your name and studentNumber

a list of source files submitted

· any specific instructions for compiling and/or running your code

2. All  of your  .c source  files and all other files needed for testing/running your programs.

3. Any output files required, if there are any.

The code MUST compile and run on the course VM.

· If your internet connection at home is down or does not work, we will not accept this as a reason for

handing in an assignment late so make sure to submit the assignment WELL BEFORE it is due!

You WILL lose marks on this assignment if any of your files are missing. So, make sure that you hand  in the correct files and version of your assignment. You will also lose marks if your code is not written neatly with proper indentation and containing a reasonable number of comments. See course

notes for examples of what is proper indentation, writing style and reasonable commenting).