## 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 with exit code 0.

##### Example

See .

#### `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 ).

    (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 .

#### `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 .

##### Example

See .

#### `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 .

#### `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 .

##### Example

See

#### `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 , which has a function associated as per 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 .

    (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 .

##### Example

See .

#### `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 , associates a function to it and then starts it using .

##### 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))