Øvelse+4+-+Posix+Threads

=Exercise 1 Creating Posix Threads= Write a program that creates two threads. When created, the threads must be passed an ID which they will print to stdout every second along with the number of times the thread has printed to stdout. When the threads have written to stdout 10 times each, they shall terminate. The main function must wait for the two threads to terminate before continuing (hint: Look up pthread join).

A possible output from running the program is:

$ ./lab Main: Creating threads Main: Waiting for threads to finish Hello #0 from thread 0 Hello #0 from thread 1 Hello #1 from thread 0 Hello #1 from thread 1 ... Hello #9 from thread 0 Hello #9 from thread 1 Thread 0 terminates Thread 1 terminates Main: Exiting

code format="cpp"
 * Code - threads_1.cpp:**
 * 1) include
 * 2) include 

void *Thread0(void *Ptr) // ***OBS*** Skal være void pointer { for(int i = 1;i<11;i++) {   std::cout << "Hello #" << i << " from thread 0" << std::endl; sleep(1); } }

void *Thread1(void *Ptr)// ***OBS*** Skal være void pointer {

for(int i = 1;i<11;i++) {   std::cout << "Hello #" << i << " from thread 1" << std::endl; sleep(1); } }

int main { pthread_t thread0, thread1; //Thread ID

pthread_create(&thread0, NULL, Thread0, NULL); //Create a new thread pthread_create(&thread1, NULL, Thread1, NULL);

pthread_join(thread0, NULL); //Wait for thread Terminates pthread_join(thread1, NULL);

return 0; } code

code g++ threads_1.cpp -o threads_1 -lpthread //-lpthread link to libary ./threads_1 code
 * Compile:**

// The program will shut down when the two threads are done. .. Join waits for a thread to terminate. //
 * What happens if main returns immediately after creating the threads? Why?**

//Synopsis:// To use pthread must we include  //Description:// used to create a thread, first argument (&thread0) is a reference to thread name given in "pthread_t", second argument (NULL) is an attribute, third argument (Threadx) is the function to be called, last argument (NULL) is the thread ID.
 * Comment: **
 * //pthread_create://**

//Synopsis:// To use pthread must we include  //Description:// takes two arguments: first argument (threadX) is the name of the thread to wait for. second argument (NULL) is a pointer to where pthread_exit shall store the return value from the exiting thread.
 * //pthread_join://**

=Exercise 2 Sharing data between threads= Create a program that creates two threads, incrementer and reader. The two threads share an unsigned integer variable named shared which is initially 0. incrementer increments shared every second while reader reads it every second and outputs it to stdout.

Figure 2.1: incrementer and reader thread utilizing the shared variable shared

code format="cpp"
 * Code - threads_2.cpp:**
 * 1) include
 * 2) include 
 * 3) include 

int shared = 0; //global int accessible by both threads..

void *incrementer(void *Ptr) // ***OBS*** Skal være void pointer { for(shared=0; shared < 11;shared++) //run 10 times {   sleep(1); } }

void *reader(void *Ptr)// ***OBS*** Skal være void pointer { while(shared < 11) //untill {     std::cout << "Shared: " << shared << std::endl; //print to stdout sleep(1); } }

int main { pthread_t thread0, thread1; //Thread ID's

pthread_create(&thread0, NULL, incrementer, NULL); //Create the threads pthread_create(&thread1, NULL, reader, NULL);

pthread_join(thread0, NULL); //Wait for thread Termination pthread_join(thread1, NULL);

return 0; } code // Because the threads aren't synchronized, "shared" will be incremented  be fore it has been read. (this is not the case, at all times, but nothing has been done to make sure it will NOT happen) //
 * Are there any problems in this program? Do you see any? Why (not)?**

=Exercise 3 Sharing a Vector class between threads= The supplied class Vector1 holds 10.000 elements that should at all times have the same value. Vector::setAndTest sets the value of the elements and then immediately checks that the Vector object is consistent (all elements hold the expected value).

Create a thread function writer that uses Vector::setAndTest to set and test the value of a shared Vector object. Then create a main function that creates a user-defined number of writer threads (between 1 and 100), each with their own unique ID. Let each writer set and test the shared Vector object to its ID every second. If a writer detects an inconsistency in the shared Vector object (i.e. setAndTest returns false), it should write an error message. Run the program with a number of threads.

code format="cpp"
 * Code - threads_3.cpp:**
 * 1) include
 * 2) include  //to use threads
 * 3) include  //to use sleep
 * 4) include "Vector.hpp" //the thing with the thing :)

Vector v; //instantiate Global Vector object, defined in Vector.hpp.

void *writer(void *ID) // ***OBS*** Skal være void pointer { while(1) { if(v.setAndTest((int)ID) == false) //the ID is used as the number to write.. CLEVER! std::cout << "setAndTest Error! \n"; else std::cout << "setAndTest succes! \n"; sleep(1); } }

int main { int antal; std::cout << "How many threads, would you like to start?: "; std::cin >> antal;

pthread_t thread[antal];

for(int i = 0; i < antal; i++) { pthread_create(&thread[i], NULL, writer, (void*)i); //Create the threads with incementing ID's }

std::cout << "press CTRL+C to end this madness\n";

pthread_exit(NULL); //Exit terminate the calling thread

return 0; } code

//No, the writer doesnt make any problems. But if that does there are a collisions between two threads, because they use the same variable before the second one is finished. //
 * Do your writers detect any problems? Are there any problems in this program? Do you see them? Why do (not) see them?**


 * Comment:**

=Exercise 4 Tweaking parameters= Modify your program from exercise 3 so that the writers loop time is no longer one second but a user-de ned number of microseconds. Experiment with the number of writers created and shorter loop time - do you see any problems? Explain when and why they start to occur, and why you did not see them in exercise 3.

code format="cpp"
 * Code - threads_4.cpp:**
 * 1) include
 * 2) include 
 * 3) include 
 * 4) include "Vector.hpp"

Vector v; //Global Vector object

int sec; //used by all threads to determine sleep time.

void *writer(void *ID) // ***OBS*** Skal være void pointer { while(1) { if(v.setAndTest((int)ID) == false) std::cout << "setAndTest Error! \n"; else std::cout << "setAndTest succes! \n"; usleep(sec); } }

int main { int antal;

std::cout << "How many threads would you like to start?"; std::cin >> antal; std::cout << "How many microseconds between execution of a thread?: "; std::cin >> sec;

pthread_t thread[antal];

for(int i = 0; i < antal; i++) { pthread_create(&thread[i], NULL, writer, (void*)i); //Create a new thread }

std::cout << "Press CTRL+C to end tis madness!\n\n\n";

pthread_exit(NULL); //Exit terminate the calling thread

return 0; } code


 * Do your writers detect any problems? Are there any problems in this program? Do you see them? Why do (not) see them?**

An occasional collission is spotted where one thread executes before another is finished.. on a 2.2Ghz Intel Corei7, this starts to happen regularly at around 6000 threads with 1 µS delay.

=Exercise 5 Testing on target= Recompile the solution from exercise 3 and test it on target following the same line of thinking as in exercise 4. Compare your ndings with those in that of exercise 4. Is there any dierence in when you see errors on host and targets?

compilation for target: code format="bash" arm-angstrom-linux-gnueabi-g++ threads_4.cpp -o threads_4.target -lpthread code

pushing and executing: code format="bash" push threads_4.target

8000

./threads_4.target code

there's a lot more collisions on the devkit! A LOT!

Target only has one core and can only give time to one thread at a time in contrast to our host which has 4 cores. (and more time to give)