How to daemonize a process that inherits all parents threads? - operating-system

I have a process that creates multiple threads and creates a socket.
Now i want to create a daemon process by calling a fork() and exit the parent process.
But the threads that are created by parent process get exited when parent is killed.
Is there a way I can inherit those threads and socket to child process ?
(Code is run in CPP)

But the threads that are created by parent process get exited when parent is killed.
Not exactly. The parent's threads are unaffected, and the child only ever gets the thread that called fork(). This is not the same thing as the child getting the other threads, and them thereafter terminating. In particular, no cancellation handlers or exit handlers that may have been registered by them are called in the child, and this may leave mutexes and other synchronization objects in an unusable and unrecoverable state. Cleaning up such a mess is the intended purpose of fork handlers, but those are tricky to use correctly, and they must be used consistently throughout the process to be effective.
I there a way I can inherit those threads and socker to child process ?
A child process inherits its parent's open file descriptors automatically, so nothing special needs to be done about the socket. But the other threads? No.
The POSIX documentation for fork is explicit about all this:
The new process (child process) shall be an exact copy of the calling
process (parent process) except as detailed below:
[...]
The child process shall have its own copy of the parent's file descriptors. Each of the child's file descriptors shall refer to the
same open file description with the corresponding file descriptor of
the parent.
[...]
A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a
replica of the calling thread and its entire address space, possibly
including the states of mutexes and other resources. Consequently, to
avoid errors, the child process may only execute async-signal-safe
operations until such time as one of the exec functions is called.
When the application calls fork() from a signal handler and any of the fork handlers registered by pthread_atfork() calls a function that
is not async-signal-safe, the behavior is undefined.
If the objective of forking is to disassociate from the original session and parent in order to run in the background as a daemon, then your best bet is for the initial thread to do that immediately upon startup, before creating any additional threads or opening any sockets.

Related

why it is called context switch? why not Process Swap or Swapping,cause resources are same

The process of a Context Switch. In computing, a context switch is the
process of storing and restoring the state (more specifically, the
execution context) of a process or thread so that execution can be
resumed from the same point at a later time.
but if it is the process or thread
and resource is not shared then it must be called as Process Swap or Thread Swap
It is not swapping threads themselves or process themselves. It is swapping execution context information stored within the CPU - various CPU registers, flag bits, etc. A process contains 1+ threads, and each thread manipulates CPU state. A context switch captures the CPU state (the context) of the current running thread and pauses it, then swaps in the state of another thread so it can then resume running where it previously left off.
Keep in minds that it was called a change in process context long before there were threads. Since we are talking history, I ignore threads.
Making a process executable requires loading registers. The set of registers varies among systems but it typically includes:
General Registers
Processor Status
Use Page Table Registers
When a process ceases to be current, its register values need to be saved. When the process becomes current, its register values need to be restored.
Nearly every processor has an instruction that performs each of these tasks to allow the switch to be performed atomically.
The processor then needs to define a data structure for holding the register values. For whatever reason, this data structure was called a "Process Context Block" or PCB (some idiotic textbooks use PCB to describe something else that does not really exist).
Someone probably thought calling it a Process "Context" was a cute name. It really does not make sense in English but that is what happened.
The instructions for loading and saving then became variants of Load Process Context and Save Process Context.
but if it is the process or thread and resource is not shared then it must be called as Process Swap or Thread Swap
Swapping is an entirely different concept. So the terms "swap" and "swapping" were already taken. In the days before paging, entire processes were moved (swapped) to disk. That is why eunuchs has a "swap" partition—the name never got updated to "page partition."

QUERY REGARDING PARENT AND CHILD PROCESS

Can a for loop be preempted in between?
suppose we have a parent and child proces;both have for loop execution
Can one process's for loop be preempted in between so that another process for loop is started?and if so, will it resume afterwards?
This depends obviously on the operating system used and many parameters, e.g. the priority of the processes. But generally a process can be interrupted after each machine instruction. This means it can be interrupted even within a single line of code in a language like C.
If a process has been interrupted, it will normally be resumed with the next machine instruction.

Systemverilog spawned processes execute after parent executes blocking statement

This paper titled Systemverilog Event Regions Race Avoidance & Guidelines submits an example that contradicts the Systemverilog IEEE 1800-2012 LRM:
...when forking background processes, it is often very useful to allow
newly created subprocesses a chance to start executing before
continuing the execution of the parent process. This is easily
accomplished with the following code:
program test;
initial begin
fork
process1;
process2;
process3;
join_none
#0;
// parent process continue
end
endprogram
However IEEE Systemverilog LRM IEEE 1800-2012 states:
"join_none. The parent process continues to execute concurrently with
all the processes spawned by the fork. The spawned processes do not
start executing until the parent thread executes a blocking statement
or terminates."
Which is it?
There is no contradiction here. Look at it this way:
join_none. The parent process continues to execute concurrently with all the processes spawned by the fork. The spawned processes do not start executing until the parent thread executes a blocking statement or terminates.
We are being told that the forked processes do not start immediately. They wait for the parent process, which spawned them, to yield (by either terminating or by encountering a blocking statement). The fork statement basically schedules the processes. The scheduler gets a chance to start executing them only when the already running thread (parent process) yields.
The first example you quoted, suggests that you give a chance to the spawned processes to start executing. To do so it asks you to introduce a #0 statement. When the parent process encounters #0, a blocking statement, it yields. The spawned processes therefor get a chance to start executing.

how to terminate an infinitely running process

this question was asked to me in NVIDIA interview
Q)if a process is running from infinite time and O.S. has completely lost control on it, then how would you deallocate resources from that process?
This is a very open question for which the answer depends on lot of factors like signal mechanism of the OS, fork wait exit are implemented, states in which a process can be ...etc. Your answers should have been on the following lines.
A process can be in 1 of these states: ready, running, waiting.. apart from this there is born state and terminated/zombie state. During its lifetime i.e after fork() till exit(), a process has system resources under its control. Ex:entries in process table, open files to IO devices, VM allocated, mappings in page table etc...
OS has lost complete control of the process: I interpret as follows--
----- A process can execute a system call Ex-read and the OS will put the process into sleep/waiting state. There are 2 kinds of sleep: INTERRUPTIBLE & UNINTERRUPTIBLE
After the read is done the Hardware sends a signal to the OS which will get redirected to the sleeping process. And the process will spring up to action again. There may also be a case where the read never completed so the Hardware never sent a signal.
Assume the process initiated a read (which will fail) and went to a:
a INTERRUPTIBLE SLEEP: Now the OS/parent of this process can send a SIGSTOP, SIGKILL etc to this process and it will be interrupted from its sleep and then the OS can kill the process reclaim all the resources. This is fine and solves your problem of infinite resource control.
b UNINTERRUPTIBLE SLEEP: Now even though the read has not sent any signal, but is taking infinite time, and the parent/OS knows that the read has failed likely sending SIGSTOP,SIGKILL has no effect since it is sleeping UNITERRUPTIBLY waiting for read to finish. So now the process has control over system resource and OS cant claim it back. See this for clear understanding of UNITERRUPTIBLE SLEEP. So, if a process is in this state from an infinite time, the OS or parent CANNOT kill/stop it and reclaim the resource, those resources are tied indefinitely and can be reclaimed only when the system is powered off, or you need to hack the driver where a service is struck and get it terminated by the driver which will then send the read failed signal to UNINTERRUPTIBLE PROCESS.
----- after the process has completed its execution and ready to die, the parent which created this process has not yet called wait on this child and process is in ZOMBIE state, in which case it is still hanging on to some system resources. Usually it is the job of the parent to ensure that the child it created terminates normally. But, it may be the case that the parent which was supposed to call wait on this child itself got killed, then the onus of terminating this child goes to the OS, that is exactly what init process does on UNIX like OSes. Apart from its other jobs, init acts like a foster parent for the process whoes parent are dead. It runs the check_ZOMBIE procedures every now and then ( when system resources are low) to ensure that ZOMBIES dont hang on to system resources.
From the wikipedia article : When a process loses its parent, init becomes its new parent. Init periodically executes the wait system call to reap any zombies with init as parent. One of init's responsibilities is reaping orphans and parentless zombies.
So your answer should be pointing at the way process states are defined, signal handling mechanisms are implemented and also the way init process reaps ZOMBIES etc ....
Hope it cleared a thing or two..
Cheers....

how dispatcher works?

I have recently started my OS course. As far as i know the work of dispatcher is to save the context of current process and load context of process to be run next. But how does it do that? When a process is preempted then as soon as dispatcher will be loaded and executed ( as it is also a program ) the context of previous process in registers, PSW etc will be lost. How is it going to save the context before loading itself ?
The simple answer is that modern processors offer architectural extensions providing for several banks of registers that can be swapped in hardware, so up to X tasks get to retain their full set of registers.
The more complex answer is that the dispatcher, when triggered by an interrupt, receives the full register set of the program that was running at the time of interrupt (with the exception of the program counter, which is presumably propagated through a mutually-agreed-upon 'volatile' register or some such). Thus, the dispatcher must be carefully written to store the current state of register banks as its first operation upon being triggered. In short, the dispatcher itself has no immediate context and thus doesn't suffer from the same problem.
Here is an attempt at a simple description of what goes on during the dispatcher call:
The program that currently has context is running on the processor. Registers, program counter, flags, stack base, etc are all appropriate for this program; with the possible exception of an operating-system-native "reserved register" or some such, nothing about the program knows anything about the dispatcher.
The timed interrupt for dispatcher function is triggered. The only thing that happens at this point (in the vanilla architecture case) is that the program counter jumps immediately to whatever the PC address in the BIOS interrupt is listed as. This begins execution of the dispatcher's "dispatch" subroutine; everything else is left untouched, so the dispatcher sees the registers, stack, etc of the program that was previously executing.
The dispatcher (like all programs) has a set of instructions that operate on the current register set. These instructions are written in such a way that they know that the previously executing application has left all of its state behind. The first few instructions in the dispatcher will store this state in memory somewhere.
The dispatcher determines what the next program to have the cpu should be, takes all of its previously stored state and fills registers with it.
The dispatcher jumps to the appropriate PC counter as listed in the task that now has its full context established on the cpu.
To (over)simplify in summary; the dispatcher doesn't need registers, all it does is write the current cpu state to a predetermined memory location, load another processes' cpu state from a predetermined memory location, and jumps to where that process left off.
Does that make it any clearer?
It doesn't generally get loaded in such a way that you lose the information on the current process.
Often, it's an interrupt that happens in the context of the current process.
So the dispatcher (or scheduler) can save all relevant information in a task control block of some sort before loading up that information for the next process.
This includes the register contents, stack pointer and so on.
It's worth noting that the context of the next process includes its state of being in the dispatcher interrupt itself so that, when it returns from the interrupt, it's to a totally different process.
Dispatcher module gives control of the CPU to the process selected by the short-term scheduler; this involves:
switching context,
switching to user mode,
jumping to the proper location in the user program to restart that program
The operating system's principal responsibility is controlling the execution of processes. This includes determining the pattern for execution and allocating resources to the processes.
A process may be in one of the two states :
Running or
Not Running
When the OS creates a new process, it creates a process control block for the process and enters that process into the system into the Not Running state. The process exists is known to OS and is waiting for an opportunity to execute.
From time to time, the currently running processes will be interrupted and the dispatcher portion of the OS will select some other processes to run.
During execution when the process is devoid of resources, it gets blocked. Provided those resources it re-enters the ready state and then into running state. This transition from ready to running state is done by dispatcher. Dispatcher dispatches the process.