A process is an instance of a computer program that may be running.
At the start of each program, a program gets one process, but each program can make more processes.
Powerful, but isolated! Can only communicate with each other by explicit means.

fork clones the current process to create a new process, called a child process.
it copies the state of the existing process with a few minor differences
getppid())SIGCHLD)occurs when there is an attempt to create an infinite number of processes.
This will often bring a system to a near-standstill
You do NOT want to do this (or else your VM will be difficult to recover)
#define PROC 100
int main() {
	pid_t processes[PROC];
	for (int i = 0; i < PROC; ++i) {
		processes[i] = fork();
		if (!processes[i]) {
			execlp("ruby", "ruby", "file.rb", (char*)
				NULL);
		}
	}
	for (int i = 0; i < PROC; ++i) {
		waitpid(processes[i], NULL, 0);
  }
}
int main() { 
    pid_t child1 = fork(); 
    if (!child1) { 
        pid_t child2 = fork(); 
        if (!child2) { 
            while (1) {} 
        } 
        pid_t child3 = fork(); 
        if (!child3) { 
            printf("Hello!"); 
            exit(2); 
        } 
        waitpid(child3, NULL, 0); 
        waitpid(child2, NULL, 0); 
        exit(1); } 
        waitpid(child1, NULL, 0); }

pid_t pid = fork();
if(pid == -1){
	//fork failed
}else if(pid == 0){
	//I am the child
	exec(...)
}else{
	//I Am the parent
	waitpid(pid, ...);
}
fork()creates a child process
On success, the PID of the child process is returned in the parent, and 0 is returned in the child.
On failure, -1 is returned in the parent, no child process is created
waitpid(pid, ...)wait for state changes in a child of the calling process
A state change is considered to be:
wait allows the system to release the resources associated with the child
otherwise the terminated child remains in a “zombie” state
Exec Familyreplaces the current process image with a new process image
./time <command> <args> ...sleep 2

struct timespec
    time_t tv_sec;long tv_nsec;tv_sec = 10, tv_nsec = 992300000 -> 10.9923 sec
int clock_gettime(clockid_t, timespec *);
    clockid_t: should use CLOCK_MONOTONIC in this lab./env [key=val1] [key2=val1] ... -- cmd [args] .../env TZ=EST5EDT -- date - execute date under enviornment TZ=EST5EDT./env TEMP=EST5EDT TZ=%TEMP -- date - why is this the same as above?
int setenv(const char* name, const char* value, int overwrite)
char *getenv(const char *name)%notation in a string