## Multithreading

### Multithreading Reference

`mp:all-processes`

Return the list of active processes.

#### Function

        mp:all-processes

##### Description

Returns the list of processes associated to running tasks. The list is a fresh new one and can be destructively modified. However, it may happen that the output list is not up to date, because some of the tasks has expired before this copy is returned.

`mp:exit-process`

Exit the task from which it is invoked.

#### Function

        mp:exit-process

##### Description

When called from a running task, this function immediately causes the task to finish. When invoked from the main thread, it is equivalent to invoking ref.quit with exit code 0.

##### Example

See ref.mp.interrupt-process.

`mp:holding-lock-p`

Determine whether current process holds the lock.

#### Function

        mp:holding-lock-p
        lock

`lock`

- An object of type `mp:lock`.

##### Description

Returns true if the current process holds the lock.

`mp:interrupt-process`

Interrupt a task.

#### Function

        mp:interrupt-process
        process
        function

`process`

- An object of type `mp:process`.

`function`

- A function, which is to be executed in the interrupted process.

##### Description

This function sends a signal to a running task. When the task is free to process that signal, it will stop whatever it is doing and execute the given `function`.

##### Example

Kill a task that is doing nothing (See ref.mp.process-kill).

    (flet ((task-to-be-killed ()
             (loop (sleep 1)) ; Infinite loop
    	 ))
      (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
        (sleep 10)
        (mp:interrupt-process task 'mp:exit-process)))

`mp:get-lock`

Try to obtain a lock.

#### Function

        mp:get-lock
        lock
        &optional;
        wait

`lock`

- An object of type `mp:lock`.

`wait`

- Whether to wait to obtain the lock. Defaults to &nil;.

##### Description

This function tries to obtain exclusive use of a lock. If `wait` is &t;, and another task owns the lock, it may wait until the lock has been released. If `wait` is &nil; it will return true if and only if it succeeded on acquiring the lock.

##### Example

See ref.mp.with-lock.

`mp:giveup-lock`

Release a lock we have obtained before.

#### Function

        mp:giveup-lock
        lock

`lock`

- An object of type `mp:lock`.

##### Description

This function releases a lock which had been previously obtained using ref.mp.get-lock.

##### Example

See ref.mp.with-lock.

`mp:make-lock`

Create a new lock.

#### Function

        mp:make-lock
        &key;
        name

`name`

- A symbol to name the lock. Names not be unique. It defaults to &nil;.

##### Description

This function creates a lock object that can be use to synchronize different tasks. The own is initally free and not owned by any task. Locks are typically implemented using Posix mutexes. When garbage collected, a lock is automatically freed.

##### Example

See ref.mp.with-lock.

`mp:make-process`

Create a new thread.

#### Function

        mp:make-process
        &key;
        name
        initial-bindings

`name`

- A symbol to name the process. Processes can be unnamed and names need not be unique.

`initial-bindings`

- The list of special variables which will be local to the new process. It defaults to &t;, which means copying all variables which are local to this process.

##### Description

This function creates a separate task, with a name, set of variable bindings and no function to run.

See also ref.mp.process-run-function.

##### Example

See ref.mp.process-enable

`mp:process-active-p`

Determine whether a task is running.

#### Function

        mp:process-active-p
        process

`process`

- An object of type `mp:process`.

##### Description

Returns true if the task is currently running.

`mp:process-enable`

Start up a task which was not running.

#### Function

        mp:process-enable
        process

`process`

- An object of type `mp:process`.

##### Description

The argument to this function should be a process created by ref.mp.make-process, which has a function associated as per ref.mp.process-preset but which is not yet running. After invoking this function a new thread will be created in which the associated function will be executed.

##### Example

The following is a possible implementation of ref.mp.process-run-function.

    (defun process-run-function (process-name process-function &rest args)
      (let ((process (mp:make-process name)))
        (apply #'mp:process-preset process function args)
        (mp:process-enable process)))

`mp:process-kill`

Try to stop a running task.

#### Function

        mp:process-kill
        process

`process`

- An object of type `mp:process`.

##### Description

This function tries to stop a running task. Killing a process may fail if the task has disabled interrupts.

##### Example

Kill a task that is doing nothing.

    (flet ((task-to-be-killed ()
             (loop (sleep 1)) ; Infinite loop
    	 ))
      (let ((task (mp:process-run-function 'background #'task-to-be-killed)))
        (sleep 10)
        (mp:process-kill task)))

`mp:process-name`

Return the name of a task.

#### Function

        mp:process-name
        process

`process`

- An object of type `mp:process`.

##### Description

Returns the name of the given task, if any.

`mp:process-preset`

Associate a function to a process.

#### Function

        mp:process-preset
        process
        function
        &rest;
        function-args

`process`

- An object of type `mp:process`.

`function`

- An interpret or compiled function.

`function-args`

- One or more arguments for the function above.

##### Description

This function associates a function to a stopped task. This function will be the entry point when the task is enabled in the future.

See also ref.mp.process-run-function.

##### Example

See ref.mp.process-enable.

`mp:process-run-function`

Create a task and execute a function in it.

#### Function

        mp:process-run-function
        name
        function
        &rest;
        function-args

`name`

- A symbol to name the process. Processes can be unnamed and names need not be unique.

`function`

- A function object, interpreted or compiled.

`function-args`

- One or more arguments which will be passed to the function.

##### Description

This function creates a new process using ref.mp.make-process, associates a function to it and then starts it using ref.mp.process-preset.

##### Example

As an example, the following code starts a background task that outputs a list of numbers, one every second:

    (flet ((count-numbers (end-number)
             (dotimes (i end-number)
    	   (format t "~%;;; Counting: ~i" i)
    	   (terpri)
    	   (sleep 1))))
      (mp:process-run-function 'counter #'count-numbers 10))

`mp:recursive-lock-p`

Determine whether lock is recursive or not.

#### Function

        mp:recursive-lock-p
        lock

`lock`

- An object of type `mp:lock`.

##### Description

Returns true if the lock is recursive.

`mp:with-lock`

Synchronize a piece of code between different tasks.

#### Macro

        mp::with-lock
        (lock)
        &body;
        body

##### Description

It grabs a lock, executes a piece of lisp code and releases the lock at the end. The inner forms are protected so that when any condition is signalled the lock is released.

##### Example

Ensure each task increments the counter properly. The lock is required because INCF is not an atomic operation.

    (defvar *counter* 0)
    (defvar *counter-lock* (mp:make-lock :name 'counter))

    (flet ((task (name)
            (loop while (<= *counter* 10)
    	      do (progn
                       (sleep 1)
    	           (with-lock (*counter-lock*)
                         (format t "~%;;; ~A counts ~D" name *counter*)
    		     (terpri)
                         (incf *counter*))))))
      (mp:process-run-function 'ana #'task 'ana)
      (mp:process-run-function 'jose #'task 'jose))