notes blog about

A process is the (Unix) OS abstraction for a running program. The process object allows for management of program’s use of memory, processor’s time and I/O resources. A process contains the program, libraries and a kernel data structure with information like the process’s address space map, status (ex. sleeping, stopped, runnable), owner, PID.

Modern OSs can run multiple processes at the same time - multitasking. On a multi-CPU/multi-core system the processes are really running simultaneously. On a single-CPU computer the OS switches between different processes quickly so it seems like they are running at the same time.

The processes can be cloned using the fork() function - this is the traditional approach. Another way to split the work between multiple entities is using the lighter weight threads which means multiple execution threads within a single process.

C

This is how you clone (fork) a process in C:

// gcc -Wall -o myfork myfork.c
// ./myfork
// https://www.root.cz/clanky/jak-nikdy-nespoustet-sluzbu-aneb-kdo-posila-tajemny-sigkill/

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char* argv[]) {
    pid_t pid = fork();

    if (pid == -1) {
        fprintf(stderr, "Fork failed\n");
        return 1;
    } else if (pid == 0) {
        printf("Child: pid %d\n", getpid());
        execl("/bin/echo", "/bin/echo", "Child: Hello, world!", NULL);
        return 42; // Never executed
    } else {
        printf("Parent: pid %d, child %d\n", getpid(), pid);
        int status;
        waitpid(pid, &status, 0);
        printf("Parent: child exited %d\n", status);
    }
}

Perl

This is how you clone a process in Perl:

#!/usr/bin/env perl
use strict;
use warnings;

my $pid = fork();
die "Can't fork: $!" unless defined $pid;

if ( $pid > 0 ) {    # parent process
    my ( $ppid, $pgrp ) = ( getppid, getpgrp );
    print "Parent process: PID=$$, PGRP=$pgrp, parent=$ppid, child=$pid\n";
} else {             # child process
    my ( $ppid, $pgrp ) = ( getppid, getpgrp );
    print "Child process:  PID=$$, PGRP=$pgrp, parent=$ppid, child=$pid\n";
}

Another way to create a subprocess in Perl is to use system() or exec() functions.

system() executes a command (cmd) and waits for it to exit. Return code (rc) 0 means success. Non-zero exit code indicates and error whose description can be found in $?.

Two ways of calling system():

# string will be passed to the shell for interpretation
$rc = system('cmd and args');
# shell won't get used but also you can't use shell metachars (ex. >)
$rc = system('cmd', 'and', 'args');

The exec() is like the system() but replaces the current process with the cmd. The new process will have the same PID and will share the same STDIN, STDOUT, and STDERR.

A sample use of exec():

my $child = fork();
die "Can't fork: $!" unless defined $child;
if ($child == 0) { # we are in the child now
    # reopen STDOUT onto a file
    open(STDOUT, ">", "log.txt") || die "open() error: $!";
    # execute ls in the background
    exec('ls', '-l');
    die "exec() error: $!"; # shouldn't get here
}

Sources