Miscellaneous Thoughts Nothing on the APIs Windows Concurrency Miscellaneous Thoughts Nothing on the APIs Copyright © 1997 – 2016 Curt Hill
Introduction We have previously seen the presentations on threads and synchronization Some practical details are considered Copyright © 1997 – 2016 Curt Hill
Overhead Again The best possible case is to have one process per CPU The processes do not interact Even then we have some overhead in the dispatcher When we add in OS overhead for synchronization functions and Event functions we increase the overhead Yet we should increase throughput if we do not have too many threads Copyright © 1997 – 2016 Curt Hill
Tradeoffs We would like the Critical Section or Semaphore or Mutex to cover as small an area as possible This maximizes concurrency Yet not too small or that last race error will not be eliminated Copyright © 1997 – 2016 Curt Hill
Reasoning Reasoning about sequential programs is not easy This is why programmers get such nice salaries Reasoning about concurrency is much harder We need to think about it in a different way Copyright © 1997 – 2016 Curt Hill
Handshaking The problem is that the we have two routines that need to call each other Typically the main form (or main program) has to start the thread function and the thread function has to call a function/method in the main to announce end or send message This leads to recursive includes There is the problem with the GUI not being thread safe as well How do we handle this? Copyright © 1997 – 2016 Curt Hill
Includes Recursive includes are usually prevented by defines at the top of .h files You have seen these: #ifndef __Stuff #define __Stuff … all the class #endif If these are recursive then we generally get something undefined Copyright © 1997 – 2016 Curt Hill
Includes in files Suppose that we have two classes each of which has two files GUI.CPP and GUI.H X.CPP and X.H Both the GUI and X will have a public function that may be called by the other The GUI will pass a pointer to itself to X X will use this to call the GUI back Copyright © 1997 – 2016 Curt Hill
Files X.H GUI.H class GUI; #include <X.H> class X{ … GUI * caller; public: void set(GUI * g) {caller = g;} … }; GUI.H #include <X.H> class GUI{ … X * myX; public: void callback(…); … }; GUI.CPP … myX->set(this); … void GUI::callback(…) X.CPP #include <GUI.H> … caller->callback(…); Copyright © 1997 – 2016 Curt Hill
Execution Before X gets a chance to start, GUI has passed a pointer to itself to X When X needs to communicate with GUI it uses this pointer to call one of the public methods This would include the one that signals it is complete This is an example of handshaking between the main thread of a program or class and another thread Copyright © 1997 – 2016 Curt Hill
Suspended Starts From the main routine we create the thread We often create it suspended Thus it does not start right away We then call the initialization routines One of these sets the callback pointer When preparation is done we resume the thread Then and only then does it execute Copyright © 1997 – 2016 Curt Hill
Conclusion Multiple threads and synchronization are tricky This presentation has perhaps given you enough information to do There are a demonstration programs Spawning threads We may want to write others We will now consider them Copyright © 1997 – 2016 Curt Hill