0% found this document useful (0 votes)
36 views

Creating Processes

Uploaded by

Jawad Hussain
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Creating Processes

Uploaded by

Jawad Hussain
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

Operating System

Assignment#1

Creating Processes (Windows)


The fundamental Windows process management function is Create Process, which creates
a process with a single thread. It is necessary to specify the name of an executable program file
as part of the Create Process call.
It is common to speak of parent and child processes, but these relationships are not actually
maintained by Windows. It is simply convenient to refer to the process that creates a child
process as the parent.

The following code demonstrates how to create a process.

void _tmain( int argc, TCHAR *argv[] )


{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( argc != 2 )
{
printf("Usage: %s [cmdline]\n", argv[0]);
return;
}
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line)
argv[1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block

Roll No-2017-SE-037 Section-A


Operating System
Assignment#1
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ) // Pointer to PROCESS_INFORMATION structure )
{
printf( "CreateProcess failed (%d).\n", GetLastError() );
return;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );

Creation of process in Android 


By default, all components of the same application run in the same process and most
applications should not change this. However, if you find that you need to control which
process a certain component belongs to, you can do so in the manifest file.

The manifest entry for each type of component element—


<activity>, <service>, <receiver>, and <provider>—supports
an android:process attribute that can specify a process in which that component
should run. You can set this attribute so that each component runs in its own process or
so that some components share a process while others do not. You can also
set android:process so that components of different applications run in the same
process—provided that the applications share the same Linux user ID and are signed
with the same certificates.

The <application> element also supports an android:process attribute, to set a


default value that applies to all components.

Android might decide to shut down a process at some point, when memory is low and
required by other processes that are more immediately serving the user. Application
components running in the process that's killed are consequently destroyed. A process
is started again for those components when there's again work for them to do.

Roll No-2017-SE-037 Section-A


Operating System
Assignment#1

When deciding which processes to kill, the Android system weighs their relative
importance to the user. For example, it more readily shuts down a process hosting
activities that are no longer visible on screen, compared to a process hosting visible
activities. The decision whether to terminate a process, therefore, depends on the state
of the components running in that process.

Figure for Creation Process

Creation of Process In Linux


Process Creation
Process creation in Unix is unique. Most operating systems implement a spawn mechanism to create a
new process in a new address space, read in an executable, and begin executing it. Unix takes the unusual

Roll No-2017-SE-037 Section-A


Operating System
Assignment#1

approach of separating these steps into two distinct functions: fork() and exec()8. The first, fork(), creates
a child process that is a copy of the current task. It differs from the parent only in its PID (which is
unique), its PPID (parent's PID, which is set to the original process), and certain resources and statistics,
such as pending signals, which are not inherited. The second function, exec(), loads a new executable into
the address space and begins executing it. The combination of fork() followed by exec() is similar to the
single function most operating systems provide.

Copy-on-Write
Traditionally, upon fork() all resources owned by the parent are duplicated and the copy is given to the
child. This approach is significantly naïve and inefficient in that it copies much data that might otherwise
be shared. Worse still, if the new process were to immediately execute a new image, all that copying
would go to waste. In Linux, fork() is implemented through the use of copy-on-write pages. Copy-on-
write (or COW) is a technique to delay or altogether prevent copying of the data. Rather than duplicate
the process address space, the parent and the child can share a single copy. The data, however, is
marked in such a way that if it is written to, a duplicate is made and each process receives a unique
copy. Consequently, the duplication of resources occurs only when they are written; until then, they are
shared read-only. This technique delays the copying of each page in the address space until it is actually
written to. In the case that the pages are never written—for example, if exec() is called immediately
after fork()—they never need to be copied. The only overhead incurred by fork() is the duplication of the
parent's page tables and the creation of a unique process descriptor for the child. In the common case
that a process executes a new executable image immediately after forking, this optimization prevents
the wasted copying of large amounts of data (with the address space, easily tens of megabytes). This is
an important optimization because the Unix philosophy encourages quick process execution.

fork()
Linux implements fork() via the clone() system call. This call takes a series of flags that specify which
resources, if any, the parent and child process should share (see the section on "The Linux
Implementation of Threads" later in this chapter for more about the flags). The fork(), vfork(), and
__clone() library calls all invoke the clone() system call with the requisite flags. The clone() system call, in
turn, calls do_fork().
The bulk of the work in forking is handled by do_fork(), which is defined in kernel/fork.c. This function
calls copy_process(), and then starts the process running. The interesting work is done
bycopy_process():

Roll No-2017-SE-037 Section-A


Operating System
Assignment#1

 It calls dup_task_struct(), which creates a new kernel stack, thread_info structure,


and task_struct for the new process. The new values are identical to those of the current task. At
this point, the child and parent process descriptors are identical.
 It then checks that the new child will not exceed the resource limits on the number of processes
for the current user.
 Now the child needs to differentiate itself from its parent. Various members of the process
descriptor are cleared or set to initial values. Members of the process descriptor that are not
inherited are primarily statistically information. The bulk of the data in the process descriptor is
shared.
 Next, the child's state is set to TASK_UNINTERRUPTIBLE, to ensure that it does not yet run.
 Now, copy_process() calls copy_flags() to update the flags member of the task_struct.
The PF_SUPERPRIV flag, which denotes whether a task used super-user privileges, is cleared.
The PF_FORKNOEXEC flag, which denotes a process that has not calledexec(), is set.
 Next, it calls get_pid() to assign an available PID to the new task.
 Depending on the flags passed to clone(), copy_process() then either duplicates or shares open
files, filesystem information, signal handlers, process address space, and namespace. These
resources are typically shared between threads in a given process; otherwise they are unique and
thus copied here
 . Finally, copy_process() cleans up and returns to the caller a pointer to the new child.

Back in do_fork(), if copy_process() returns successfully, the new child is woken up and run.
Deliberately, the kernel runs the child process first 9. In the common case of the child simply
callingexec() immediately, this eliminates any copy-on-write overhead that would occur if the parent ran
first and began writing to the address space.

Roll No-2017-SE-037 Section-A

You might also like