Creating Processes and Threads


Process creation on Unix-like machines is normally done in two stages. Firstly, fork() is called. This creates a child process, which is a clone of the calling (parent) process. The child process is identical (except for a few details) to the parent. Secondly, a call to one of the exec() family functions is invoked by the child which changes the program being executed by that process. For more information about fork() or exec(), see Open Group.

P.I.P.S. does not support fork() and exec() and the reasons for the same are described in the following sections. However, there are industry standard alternatives supported by P.I.P.S. and are detailed in the following sections:

Omission of fork()

A Unix-like kernel is designed with the two stage process creation in mind. On the Symbian platform (and Microsoft Windows®), the kernel was designed to create a process, which runs a single executable, in a single step.

P.I.P.S. does not implement the fork() operation because this would require an entirely new way of dealing with processes in the kernel and memory model. For example, duplicating the address space of an existing process was not something that was considered in the Symbian platform kernel's design. Symbian took this decision as the effort involved in customising this feature would be more than the benefit of providing the fork() function, especially in the provision of Pthreads. For more information about Pthreads, see the Pthread Wikipage.

Omission of exec()

On Unix-like systems, exec() is the standard way to load a process image into memory. Only the initialisation process is loaded directly into a new address space (special case code in the kernel), all other processes are loaded into an existing address space which was initially created by forking.

On the Symbian platform, the only way to load a process image into memory is using the loader. It assumes that the image is being loaded as a new process - one that owns no resources, has no open handles and so on. The change to the loader and any associated kernel changes, to support the exec() function were deemed to be too risky.

Generic IPC

P.I.P.S. supports two types of Inter-Process Communication (IPC) between processes or threads:

  • Pipes (named and unnamed): Unnamed pipes are created using pipe() and named pipes are created using mkfifo(). Pipe-based communication is also possible between a parent and a child process when the child is created using popen() or popen3().

  • Local file sockets: These correspond to sockets created with AF_LOCAL/PF_LOCAL/AF_UNIX as the address family. The semantics of their use are similar to those of their Unix equivalents.

Related information