Before we launch into how to write a service in Python, we must discuss some important service concepts. This will help you understand some of the design and implementation decisions made for Python services.
Windows NT starts a service by executing a process. Once this process starts, it’s expected to report to the SCM that it’s indeed a service and that it’s starting. It also must pass to the SCM a control handler; that is, a function that responds to control messages sent by the SCM. The service process then executes. When the service is to be stopped, the SCM notifies the control handler of the stop request. The service itself is responsible for handling this request and terminating itself.
This leads to most services, regardless of the language they are written in, being structured as follows: A main thread starts. This thread initializes itself by reporting to the SCM and passing it the control handler. Once initialization is complete, the thread starts a worker loop waiting either for work to do or a notification to stop, pause, etc. The SCM calls the control handler on another thread, so once the function receives the control notification, it reports back to the SCM it’s stopping, then triggers some synchronization object that the main thread will notice next time around the loop. As the main thread terminates, it continues to report its status to the SCM.