Processes (multitasking)
Author(s): Jose F. Morales.This library offers predicates to create, communicate, and synchronize with child processes. The child processes are duplicates of the parent process, based on the fork() function from POSIX-compatible operating systems (see man page for a precise description of the non-inherited process attributes).
The child process can execute a given goal (in a clone of the parent process) or start an external program.
Contrary to threads, processes have a separate address space and communication must be performed via inter-process communication mechanisms. This is useful for executing external programs, or implementing coarse-grained parallelism and concurrency.
- Process creation via fork() is relatively costly. Use only when address separation is necessary. Consider other concurrency primitives otherwise.
- Channels connected to in-memory terms are transmited via pipes or temporary files (when needed to avoid deadlock problems).
- Deadlock problems may still appear if the user specifies two or more pipe(_) channels for the same process (data must be send/received concurrently).
- The current implementation is not protected against Prolog signals (it can leak resources, including zombie processes, if interrupted by signals).
- Communication is currently only supported via file system, file descriptors, and sockets.
- Other mechanisms like file locks, semaphores, message queues, shared memory, etc. are not yet implemented.
- Arguments do not accept wildcards. See predicates in library(glob) for glob expansions (shell wildcard patterns).
Usage and interface
- Library usage:
:- use_module(library(process)). - Exports:
- Predicates:
process_call/3, process_pid/2, process_is_joined/1, process_join/1, process_terminate/1, process_kill/1, process_send_signal/2, process_fork/2, process_pipe/2. - Regular Types:
process/1, process_option/1, process_cmd/1, process_arg/1.
- Predicates:
- Imports:
- System library modules:
lists, port_reify, system, process_channel. - Packages:
prelude, nonpure, condcomp, assertions, regtypes, isomodes, hiord, dcg.
- System library modules:
Documentation on exports
The predicate process_call/3 waits for process completion, throwing an exception if the return code is different than 0. This default exit behaviour can be controlled with the following options:
The process standard input, output, and error file descriptors (streams from the Prolog side) can be bind to several process_channel/1:
The environment of the process can be modified with the following options:
Usage:
Options that control command execution
Usage:process_call(Cmd,Args,Opts)
Execute a command in a child process, where Cmd is the executable path. Use path(Exec) for executing a program Exec reachable from the PATH environment variable
- The following properties should hold at call time:
(process:process_cmd/1)Command for process_call/3
(basic_props:list/2)Args is a list of process_args.
(basic_props:list/2)Opts is a list of process_options.
Usage:process_pid(Process,Pid)
The POSIX PID of the process Process.
- The following properties should hold at call time:
(process:process/1)A process handler
(basic_props:int/1)Pid is an integer.
Usage:process_is_joined(Process)
The process has already been joined.
- The following properties should hold at call time:
(process:process/1)A process handler
Usage:process_join(Process)
Wait for completion of process Process.
- The following properties should hold at call time:
(process:process/1)A process handler
Usage:process_terminate(Process)
Sends POSIX signal SIGTERM to the process Process, which asks politely for process termination.
- The following properties should hold at call time:
(process:process/1)A process handler
Usage:process_kill(Process)
Sends POSIX signal SIGKILL to the process Process, which forces process termination.
- The following properties should hold at call time:
(process:process/1)A process handler
Usage:process_send_signal(Process,Signal)
Sends POSIX signal Signal to process Process.
- The following properties should hold at call time:
(process:process/1)A process handler
(basic_props:int/1)Signal is an integer.
Usage:process_fork(Goal,Opts)
Execute Goal in a forked process.
- The following properties should hold at call time:
(basic_props:callable/1)Goal is a term which represents a goal, i.e., an atom or a structure.
(basic_props:list/2)Opts is a list of process_options.
Usage:process_pipe(Cmd,Opts)
Execute the list Cmds of process_call/3, connecting standard input and output of consecutive processes with pipes.
Options are passed as follows: input redirection options are applied to the first process; output redirection and status are applied to the last process; the rest of options are applied to all commands. Background execution is not currently supported (see internal documentation for details).
Known bugs and planned improvements
- (feature) Poll if a process has terminated
- (feature) Support more IPC primitives (file locks, semaphores, shared memory, etc.).
- (feature) Fix asynchronous data transmission using POSIX select? We may avoid temporary files then.
- (feature) Complete support for daemons (see example)
- (feature) Put together with other concurrency and parallelism libraries in Ciao
- (performance) Consider using posix_spawn for exec (faster, works in systems without MMU).
- (performance) Write benchmarks (see internal documentation)
- (stability) Protect against signals
- (stability) Pending safety checks? Close file descriptors in child process?
- (mingw) Add Windows specific options to create processes in a new console and create new process groups. Process groups will be necessary for killing subprocess using process_kill/1.
- Background execution is not supported in process_pipe/2. That requires the creation of a new process abstraction to group together several processes. This compound process would be user-based and then, it is not clear that it belongs to this module.