Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>It appears that you are confusing the pthread_t management variable, <code>planes</code>, with the variable containing the flight data, <code>flights</code>.</p> <p>The pthread_t management variable, <code>planes</code>, is used by the pthread library and you should really only be using it as an argument to pthread library calls, otherwise just leave it alone and do not worry about it. Think of the variable <code>planes</code> as a storage area that you create and then give to the pthread library to use and by doing so you give ownership of that variable to the pthread library.</p> <p>So the first order of business is to separate out and make distinct the difference between the pthread management and the actual data that is being manipulated by the threads.</p> <p>You have several places where you are using the pthread management variable, <code>planes</code>, as if it is a flight data variable. It is not. Replace <code>planes</code> with <code>flights</code></p> <pre><code> if((flights[t].startState)==1){ std::cout &lt;&lt; "Flight # " &lt;&lt; flights[t].fid &lt;&lt; " is listed as waiting at the gate." &lt;&lt; std::endl; void takeoff(); //go to takeoff function and go through switch case } if((flights[t].startState)==2){ std::cout &lt;&lt; "Flight # " &lt;&lt; flights[t].fid &lt;&lt; " is listed as waiting to land." &lt;&lt; std::endl; //go to landing function and go through switch case } </code></pre> <p>This bit of source in your function <code>StartState()</code> does not make sense.</p> <pre><code>for(int i = 0; i&lt;NUM_THREADS; i++){ startState = rand() % 1+2; } startState = my_flights-&gt;startState; </code></pre> <p>I suppose you are wanting to set a start state of a particular flight with some random start state. So I would expect the source to look like the following as I assume you are interested in setting the start state for a specific flight and the loop does not really do anything except exercise the random number generator <code>NUM_THREADS</code> times so the loop should just be replaced by something like the following. However I have not checked your logic on this and whether the range is correct or anything. </p> <pre><code>my_flights-&gt;startState = rand() % 1+2; </code></pre> <p><strong>A Suggested Course of Action</strong></p> <p>You should think of a thread as being a little program or application. I suggest that for this simple example that you first of all write your flight logic without worrying about threads. So if you start with a function, say <code>FlyPlaneFlight ()</code> to which you pass a flight variable and this function then calls other functions to do various things and when the flight ends, it returns to the caller, you will probably be in a good place for the threads. After having the logic in place for a single flight, you then use the pthread library to create multiple flights by initializing the flight data, and then creating a thread, that uses <code>FlyPlaneFlight()</code>.</p> <p>You also need to consider time and interaction. For this kind of a simulation, I suspect that you will want to have the <code>FlyPlaneFlight()</code> function to have a loop in which changes are made to the flight data and then the thread will sleep for a second or two. As a beginning test, use a for loop with a definite number of iterations and will then exit such as the following:</p> <pre><code>for (int i = 0; i &lt; 100; i++) { // modify the flight data sleep(1000); // sleep for a second (1000 milliseconds) then repeat } </code></pre> <p>If this becomes more complicated so that the flights are not independent but must be synchronized in some way, you will need to look into the thread synchronization functions of the pthread library.</p> <p>So when you wrap your <code>FlyPlaneFlight()</code> function into a <code>pthread_create()</code> function, it might look something like the following source snip:</p> <pre><code>void *FlightID(void *flightdata){ struct flight_data *my_flights = (struct flight_data*)flightdata; // initialize the flight data as needed FlyPlaneFlight (myFlight); // print out the myFlight data so that you can see what happened pthread_exit(NULL); } </code></pre> <p>The idea is to treat the plane flight as an object and all of the needed data for the flight is in the <code>struct flight_data</code> struct and that for the most part you can ignore the pthread library which is not involved in the actual flying simulation but rather is used to allow for the simulation of multiple flying objects. So you create multiple threads, each of which has its own flight data and then uses the same code to process the flight data. You do a bit of randomization so that all of the various flights will have different histories, they will do different things.</p> <p><strong>Edit</strong></p> <p>Your main would then have a loop something like the following</p> <pre><code>for (t=0; t&lt;NUM_THREADS; t++){ //loop creates threads(flights) std::cout &lt;&lt; "In main: Creating flight " &lt;&lt; t+1 &lt;&lt; std::endl; flights[t].fid= t+1; rc = pthread_create(&amp;planes[t], NULL, FlightID, (void *)&amp;flights[t]); if (rc){ std::cout &lt;&lt; "ERROR: return code from pthread_create() is " &lt;&lt; rc &lt;&lt; std::endl; return (-1); } std::cout &lt;&lt; "Created flight " &lt;&lt; t &lt;&lt; std::endl; } pthread_exit(NULL); // exit the main thread and allow remaining threads to complete </code></pre> <p>This will create your various threads and let them run. In the loop in the <code>FlyPlaneFlight()</code> function you would have the status print outs something like the following each time through the loop so your <code>FlyPlaneFlight()</code> function would look something like and you would use a kind of <a href="http://en.wikipedia.org/wiki/Finite-state_machine" rel="nofollow">finite state machine</a> to move from state to state possibly using a random number generator to roll a virtual dice using the <a href="http://www.cplusplus.com/reference/cstdlib/rand/" rel="nofollow">rand() function as in these examples</a> to determine the next state or to remain in the current state:</p> <pre><code>void FlyPlaneFlight (struct flight_data *my_flights) { for (int i = 0; i &lt; 100; i++) { switch (my_flights-&gt;startState) { case 1: std::cout &lt;&lt; "Flight # " &lt;&lt; my_flights-&gt;fid &lt;&lt; " is listed as waiting at the gate." &lt;&lt; std::endl; // now move the flight state to the next state. break; case 2: std::cout &lt;&lt; "Flight # " &lt;&lt; my_flights-&gt;fid &lt;&lt; " is listed as waiting to land." &lt;&lt; std::endl; // now move the flight state to the next state. break; // other case statements for other flight states and moving between the // various flight states. } sleep (1000); // sleep this thread for one second (1000 milliseconds) then repeat } } </code></pre> <p><strong>EDIT #2 based on source update 10/06 at 22:37</strong></p> <p>In your source you have a global array variable, <code>flights</code>, that you are trying to access directly through out your source. This is a mistake that is leading you into problems. What you need to do is to have your thread create call to allocate a particular array element of flights to the particular thread. Then at that point you do not worry about the flights array but instead work with only the particular element assigned to that thread.</p> <p>For instance use the thread create as follows which creates a thread and assigns a unique array element to the thread being created.</p> <pre><code>rc = pthread_create(&amp;planes[t], NULL, FlightID, (void *)&amp;flights[t]); </code></pre> <p>The thread entry function, <code>FlightID()</code> accepts as an argument a pointer to that array element so at that point any of your functions that operate on the flight data in <code>flights[t]</code> can just use that pointer to that array element. The functions should only be worried about their particular flight and not everyone else's flight as well.</p> <p>Also after the thread is started, the function <code>FlightID()</code> and any function it calls should no longer be concerned about other threads so all these loops with <code>NUM_THREADS</code> in these functions should not be there.</p> <p>The idea is to have a small program that is started by calling <code>FlightID()</code> which operates on the particular flight. Then with multiple threads each thread starts at <code>FlightID()</code>. So this is similar to the idea of <code>main()</code> being the entry point for a C/C++ program where <code>main()</code> has some arguments and your program starts at main(). In the case of threads, the thread starts at the thread entry function which in your case is <code>FlightID()</code>.</p> <p>The reason I have a loop in FlyPlaneFlight() is to provide a series of state changes for a finite state machine for a particular flight. In other words what is inside the loop is a plane flight.</p> <p>Look at the difference between my suggested thread creation loop and your's. Mine does nothing more than create threads. Your's creates threads and then tries to do things with the flights array element which really should now belong to the thread created and not the main.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload