Thread Structure ---------------- Threads can be very useful programming constructs. They can also result in a severe increase in program complexity. Each thread is essentially a separate process, but all threads in a process share memory. Being able to share memory makes communications between threads much simpler then communications between process, but it also greatly increases the likelihood of race conditions and system lockup. As a rule, adding the complexity of threads is only practical in a few situations. - Multiprocessor systems. Threads can greatly reduce the execution time on certain types of programs when running on multiprocessor systems. - Communications. A multithreaded program can easily wait indefinitely on one or more file descriptors without interfering with other operations. - Very long computations. It is often better to place a very long computation in a thread so that the program can still respond to requests while the computation is taking place. Poco is multithreaded to avoid communication problems. Poco is a server, and must be responsive to user requests. However, it is more important that user requests and communication problems do not interfere with Poco's control of the telescope. By using separate threads, the possibility of communication problems resulting in loss of telescope control is greatly reduced, and user messages can be answered in a timely fashion. Poco is comprised mostly of event driven threads. An event driven thread receives messages from other threads or itself. It then answers each message in turn, finishing each before moving on to the next. These messages can be prioritized if needed, and threads sleep if they have no pending messages. The advantage of using event based threads is that they are easier to program then other methods, and usually less risky then trying to use regions of mutual exclusion or other similar techniques. Event threads (see CEventThread) typically have only one or two areas per thread where areas of mutual exclusion are essential, but several threads trying to share several pieces of information can result in dozens of mutual exclusion regions each of which must be accessed in a specific order or the process will hang. While event driven threads are helpful for avoiding lockup states, race conditions can still be a problem. Poco Threads ------------ Poco consists of the following threads Main | Central |______________________ | | \ GalilBinary GalilText x * TrafficConnection Main - The Main thread is the thread started by the operating system. It is tricky to get the main thread to behave as an event driven thread, so it starts the Central thread and then goes to sleep waiting for the Central thread to terminate. Central - The Central thread is where almost all the decision making occurs. It creates the threads responsible for talking to hardware and network sockets, and then handles the messages sent by the child threads to control the telescope and communicate with other processes. GalilBinary - The GalilBinary thread listens to the binary output of the Galil motor controller card. This output comes about once every 8 milliseconds. When the Central receives this message, it recalculates all position and movement information. The GalilBinary thread is the primary means by which Poco knows the current state of the telescope. GalilText - The GalilText thread is the method by which Poco sends commands to the Galil motor control card. The text communications also indicate if the Galil card understood the previous message. TrafficConnection - The TrafficConnection thread or threads each can connect to a different Traffic server. Usually, Poco only needs to connect to one Traffic server, but it can easily spawn a connection to another one if needed. Poco uses the Traffic server to communicate with other processes like user GUI's or the Guide Camera.