4 ms·
So how does this work in windows? Edit, as for some reason it's getting downvoted: In windows, do you have to do the double fork etc? Do you have to close FDs e
by bfuclusion 6y ago
So how does this work in windows?
Edit, as for some reason it's getting downvoted:
In windows, do you have to do the double fork etc? Do you have to close FDs etc?
- meddlepal 6y agoWindows has a services abstraction though I'm admittedly not very familiar with it. I suspect there's not a lot of Win-dev folks on HN.
- bfuclusion 6y agoYeah, I've done some python daemons in win, and registered with the service control manager, but I was wondering what the "magic" was there.
- Joker_vD 6y agoThe Service Control Manager (SCM) has a list of settings for registered services: the parameters of a service are its name, executable path, arguments, environment variables, user to run it under, other services it depends on, restarting options, etc. When the system is started, the SCM starts those services. When the system is being shut down, the SCM stops them. How is a service started? The SCM launches the specified executable, in the way it's specified in the service's settings and... that's pretty much it. However, the service is supposed to support a certain protocol of interaction with SCM. First of all, the service must quickly (within half a minute from the start, IIRC) call the WinAPI function StartServiceCtrlDispatcher() on its main thread. That's basically a pre-written main(): it returns only after the service has been stopped. It takes several function pointers: to the ServiceMain where the service proper is supposed to be, and various event handlers (pause/resume/stop requests, system is shutting down, etc). It creates a separate thread to run the ServiceMain on, and then basically loops processing requests/events from the SCM (event handlers are run on the main thread). That's basically it. Nothing prevents one to write an application that can run both as a service and stand-alone: put your logic in ServiceMain, call StartServiceCtrlDispatcher with it, if it returns ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (that means you're not being launched by the SCM), call ServiceMain by yourself. Ctrl-C handler and "stop the service" handler are easily unified because on Windows, Ctrl-C handler always runs on a different thread. You just need make sure that your ServiceMain function can be safely signaled that it needs to stop from a different thread, but that's what thread-communication primitives are for.
- vbitz 6y agoWindows runs services underneath the Service Control Manager (https://docs.microsoft.com/en-us/windows/win32/services/service-control-manager https://docs.microsoft.com/en-us/windows/win32/services/serv...). Services are expected to talk to the service control manager and at least announce when they started. Services are also regularly run on different account especially the ones under "NT AUTHORITY" like "SYSTEM" and "NETWORK SERVICE". As I recall Visual Studio contains some pretty good templates for writing services with C# but the underlying requirements are abstracted by the .net Framework.
- cpascal 6y agoThere’s some Win32 stuff you can hook into with your code for service management. These are things like service startup, shutdown, pause and resume. I can’t speak to the Win32 stuff, but .NET abstracts this and you just override a base class to hook into the service stuff. Windows then has a command `sc` to register your EXE as a service and then configure things like auto-start and service restarts. Alternatively, MSI’s can be crafted to configure your EXE as a service at install time. IMO a lot of parts of Windows are a pain to develop on compared to Linux, but creating and managing services are one of the better/smoother parts.
- taneq 6y agoOn Windows, services are special executables that are installed as services and managed by Windows. https://docs.microsoft.com/en-us/dotnet/framework/windows-services/introduction-to-windows-service-applications https://docs.microsoft.com/en-us/dotnet/framework/windows-se...
- tsimionescu 6y agoWindows doesn't have fork() or any direct equivalent (instead, Windows has the CreateProcess() familiy of functions, that work essentially like fork()+exec()). Now depending on what you actually want to do, you have some options: - Use the Windows Services API to ask Windows to start and manage your process as a system service - this is closest to a SystemD demon - Create a GUI process with WindowStyle=hidden (this will be part of the current user's session) - Create a Console process with the DETACHED_PROCESS flag, which should work similarly to the above - Use one of the CreateProcessAsUser() family of functions to create a process for another user - this should allow the process to run in the background, and allow it to persist even if the current user signs off In all cases above, you can simply tell CreateProcess* that the child process should not inherit any FDs. You should probably also use the PROC_THREAD_ATTRIBUTE_PARENT_PROCESS flag to spawn this process as the child of some other long-running process, to ensure that the child process is not part of the same Job that the current process may be (usually, when a Job is finished, all processes in that job and any child they spawned, recursively, are killed).
- Joker_vD 6y agoJobs, more precisely, nested jobs, are one of the best things (IMHO) that were added to Windows 8 from a technical point of view (then again, there ain't many good things added in Windows 8). I had to write a work-manager sort of application that would need to start worker subprocesses (which may also start some other subprocesses, which may or may not be programs under my control) and one of the requirements was that if the main process crashed, all the worker processes should be terminated (imagine if a part of what a worker process is supposed to do is to listen on some well-known TCP ports and provide an HTTP API on it: you can't restart the main process without killing the workers off first). On Linux, it turned out to be surprisingly tricky. Process groups and sessions are not nested, you can easily break out of them and in fact there were some programs we needed to use that insisted on doing daemonization. Thankfully the most important one had a "--foreground" flag but it still was buggy: this program sends SIGTERM to its process group as part of a shutdown — so it kills its parent, too. Amazing. In the end I believe we ended running each worker process as a separate Docker container. Then there is a dance of waiting (or not waiting? SIGCHILD is truly horrible) on children PIDs to detect the crashes and unexpected hang in the shutdown (the worker process sends "I am done" notification to the parent, but then for some reason doesn't exit). The main process had to be made a sub-reaper to do all of that more or less reliably, and even then there were some strange sightings (signal handling is fun!). On Windows, we just shoved each worker process into its own unbreakable-from job, and that was it. The main process dies for whatever reasons, its children just disappear. A worker process dies, its children just disappear, without affecting any other worker processes and their children. Detecting termination of the child processes too was a breeze: on Windows, when you spawn a child process you get not only its PID, but also a handle (think "file descriptor") to it. This handle refers exactly to this process, and you can (interruptibly) wait on it, and when the last open descriptor to a process is closed, the process is deleted from the process table. That's why BTW there is no PID 1 that is constantly reaping its children on Windows: each process implicitly has its own handle alway open, so if the parent exits before the child does, nothing bad happens: The child process had 2 open handles on it, now it has 1. When it itself exits, the last handle is dropped, and the slot in the process table is cleaned. TL;DR: Process management is horrible, use Erlang.