Ejecución concurrente
*********************

Los módulos descritos en este capítulo proveen soporte para la
ejecución concurrente de código. La elección de qué herramienta
utilizar depende de la tarea a ejecutar (vinculada a CPU o vinculada a
E/S) y del estilo preferido de desarrollo (multi-tarea cooperativa o
multi-tarea apropiativa). A continuación se muestra un resumen:

* "threading" --- Thread-based parallelism

  * "active_count()"

  * "current_thread()"

  * "excepthook()"

  * "__excepthook__"

  * "get_ident()"

  * "get_native_id()"

  * "enumerate()"

  * "main_thread()"

  * "settrace()"

  * "settrace_all_threads()"

  * "gettrace()"

  * "setprofile()"

  * "setprofile_all_threads()"

  * "getprofile()"

  * "stack_size()"

  * "TIMEOUT_MAX"

  * Datos locales del hilo

    * "local"

  * Objetos tipo hilo

    * "Thread"

      * "start()"

      * "run()"

      * "join()"

      * "name"

      * "getName()"

      * "setName()"

      * "ident"

      * "native_id"

      * "is_alive()"

      * "daemon"

      * "isDaemon()"

      * "setDaemon()"

  * Objetos tipo *lock*

    * "Lock"

      * "acquire()"

      * "release()"

      * "locked()"

  * Objetos *Rlock*

    * "RLock"

      * "acquire()"

      * "release()"

  * Objetos condicionales

    * "Condition"

      * "acquire()"

      * "release()"

      * "wait()"

      * "wait_for()"

      * "notify()"

      * "notify_all()"

  * Objetos semáforo

    * "Semaphore"

      * "acquire()"

      * "release()"

    * "BoundedSemaphore"

    * Ejemplo de "Semaphore"

  * Objetos de eventos

    * "Event"

      * "is_set()"

      * "set()"

      * "clear()"

      * "wait()"

  * Objetos temporizadores

    * "Timer"

      * "cancel()"

  * Objetos de barrera

    * "Barrier"

      * "wait()"

      * "reset()"

      * "abort()"

      * "parties"

      * "n_waiting"

      * "broken"

    * "BrokenBarrierError"

  * Uso de *locks*, condiciones y semáforos en la declaración "with"

* "multiprocessing" --- Process-based parallelism

  * Introducción

    * La clase "Process"

    * Contextos y métodos de inicio

    * Intercambiando objetos entre procesos

    * Sincronización entre procesos

    * Compartiendo estado entre procesos

    * Usando una piscina de trabajadores (*pool of workers*)

  * Referencia

    * "Process" y excepciones

      * "Process"

        * "run()"

        * "start()"

        * "join()"

        * "name"

        * "is_alive()"

        * "daemon"

        * "pid"

        * "exitcode"

        * "authkey"

        * "sentinel"

        * "terminate()"

        * "kill()"

        * "close()"

      * "ProcessError"

      * "BufferTooShort"

      * "AuthenticationError"

      * "TimeoutError"

    * Tuberías (*Pipes*) y Colas (*Queues*)

      * "Pipe()"

      * "Queue"

        * "qsize()"

        * "empty()"

        * "full()"

        * "put()"

        * "put_nowait()"

        * "get()"

        * "get_nowait()"

        * "close()"

        * "join_thread()"

        * "cancel_join_thread()"

      * "SimpleQueue"

        * "close()"

        * "empty()"

        * "get()"

        * "put()"

      * "JoinableQueue"

        * "task_done()"

        * "join()"

    * Miscelánea

      * "active_children()"

      * "cpu_count()"

      * "current_process()"

      * "parent_process()"

      * "freeze_support()"

      * "get_all_start_methods()"

      * "get_context()"

      * "get_start_method()"

      * "set_executable()"

      * "set_forkserver_preload()"

      * "set_start_method()"

    * Objetos de conexión *Connection Objects*

      * "Connection"

        * "send()"

        * "recv()"

        * "fileno()"

        * "close()"

        * "poll()"

        * "send_bytes()"

        * "recv_bytes()"

        * "recv_bytes_into()"

    * Primitivas de sincronización (*Synchronization primitives*)

      * "Barrier"

      * "BoundedSemaphore"

      * "Condition"

      * "Event"

      * "Lock"

        * "acquire()"

        * "release()"

      * "RLock"

        * "acquire()"

        * "release()"

      * "Semaphore"

    * Objetos compartidos "ctypes"

      * "Value()"

      * "Array()"

      * El módulo "multiprocessing.sharedctypes"

        * "RawArray()"

        * "RawValue()"

        * "Array()"

        * "Value()"

        * "copy()"

        * "synchronized()"

    * Administradores (*Managers*)

      * "Manager()"

      * "BaseManager"

        * "start()"

        * "get_server()"

        * "connect()"

        * "shutdown()"

        * "register()"

        * "address"

      * "SyncManager"

        * "Barrier()"

        * "BoundedSemaphore()"

        * "Condition()"

        * "Event()"

        * "Lock()"

        * "Namespace()"

        * "Queue()"

        * "RLock()"

        * "Semaphore()"

        * "Array()"

        * "Value()"

        * "dict()"

        * "list()"

      * "Namespace"

      * Administradores customizables (*Customized managers*)

      * Utilizando un administrador remoto

    * Objetos Proxy (*Proxy Objects*)

      * "BaseProxy"

        * "_callmethod()"

        * "_getvalue()"

        * "__repr__()"

        * "__str__()"

      * Limpieza (*Cleanup*)

    * Piscinas de procesos (*Process Pools*)

      * "Pool"

        * "apply()"

        * "apply_async()"

        * "map()"

        * "map_async()"

        * "imap()"

        * "imap_unordered()"

        * "starmap()"

        * "starmap_async()"

        * "close()"

        * "terminate()"

        * "join()"

      * "AsyncResult"

        * "get()"

        * "wait()"

        * "ready()"

        * "successful()"

    * Oyentes y clientes (*Listeners and Clients*)

      * "deliver_challenge()"

      * "answer_challenge()"

      * "Client()"

      * "Listener"

        * "accept()"

        * "close()"

        * "address"

        * "last_accepted"

      * "wait()"

      * Formatos de dirección (*Address formats*)

    * Llaves de autentificación

    * *Logging*

      * "get_logger()"

      * "log_to_stderr()"

    * El módulo "multiprocessing.dummy"

      * "ThreadPool"

  * Pautas de programación

    * Todos los métodos de inicio

    * Los métodos de inicio *spawn* y *forkserver*

  * Ejemplos

* "multiprocessing.shared_memory" --- Shared memory for direct access
  across processes

  * "SharedMemory"

    * "close()"

    * "unlink()"

    * "buf"

    * "name"

    * "size"

  * "SharedMemoryManager"

    * "SharedMemory()"

    * "ShareableList()"

  * "ShareableList"

    * "count()"

    * "index()"

    * "format"

    * "shm"

* El paquete "concurrent"

* "concurrent.futures" --- Launching parallel tasks

  * Objetos ejecutores

    * "Executor"

      * "submit()"

      * "map()"

      * "shutdown()"

  * ThreadPoolExecutor

    * "ThreadPoolExecutor"

    * Ejemplo de ThreadPoolExecutor

  * ProcessPoolExecutor

    * "ProcessPoolExecutor"

    * Ejemplo de *ProcessPoolExecutor*

  * Objetos futuro

    * "Future"

      * "cancel()"

      * "cancelled()"

      * "running()"

      * "done()"

      * "result()"

      * "exception()"

      * "add_done_callback()"

      * "set_running_or_notify_cancel()"

      * "set_result()"

      * "set_exception()"

  * Funciones del módulo

    * "wait()"

      * "FIRST_COMPLETED"

      * "FIRST_EXCEPTION"

      * "ALL_COMPLETED"

    * "as_completed()"

  * Clases de Excepciones

    * "CancelledError"

    * "TimeoutError"

    * "BrokenExecutor"

    * "InvalidStateError"

    * "BrokenThreadPool"

    * "BrokenProcessPool"

* "subprocess" --- Subprocess management

  * Uso del módulo "subprocess"

    * "run()"

    * "CompletedProcess"

      * "args"

      * "returncode"

      * "stdout"

      * "stderr"

      * "check_returncode()"

    * "DEVNULL"

    * "PIPE"

    * "STDOUT"

    * "SubprocessError"

    * "TimeoutExpired"

      * "cmd"

      * "timeout"

      * "output"

      * "stdout"

      * "stderr"

    * "CalledProcessError"

      * "returncode"

      * "cmd"

      * "output"

      * "stdout"

      * "stderr"

    * Argumentos frecuentemente empleados

    * El constructor de Popen

      * "Popen"

    * Excepciones

  * Consideraciones sobre seguridad

  * Objetos Popen

    * "poll()"

    * "wait()"

    * "communicate()"

    * "send_signal()"

    * "terminate()"

    * "kill()"

    * "args"

    * "stdin"

    * "stdout"

    * "stderr"

    * "pid"

    * "returncode"

  * Elementos auxiliares de Popen en Windows

    * "STARTUPINFO"

      * "dwFlags"

      * "hStdInput"

      * "hStdOutput"

      * "hStdError"

      * "wShowWindow"

      * "lpAttributeList"

    * Constantes de Windows

      * "STD_INPUT_HANDLE"

      * "STD_OUTPUT_HANDLE"

      * "STD_ERROR_HANDLE"

      * "SW_HIDE"

      * "STARTF_USESTDHANDLES"

      * "STARTF_USESHOWWINDOW"

      * "STARTF_FORCEONFEEDBACK"

      * "STARTF_FORCEOFFFEEDBACK"

      * "CREATE_NEW_CONSOLE"

      * "CREATE_NEW_PROCESS_GROUP"

      * "ABOVE_NORMAL_PRIORITY_CLASS"

      * "BELOW_NORMAL_PRIORITY_CLASS"

      * "HIGH_PRIORITY_CLASS"

      * "IDLE_PRIORITY_CLASS"

      * "NORMAL_PRIORITY_CLASS"

      * "REALTIME_PRIORITY_CLASS"

      * "CREATE_NO_WINDOW"

      * "DETACHED_PROCESS"

      * "CREATE_DEFAULT_ERROR_MODE"

      * "CREATE_BREAKAWAY_FROM_JOB"

  * Antigua API de alto nivel

    * "call()"

    * "check_call()"

    * "check_output()"

  * Cómo reemplazar anteriores funciones con el módulo "subprocess"

    * Cómo reemplazar la sustitución de órdenes de **/bin/sh**

    * Cómo remplazar los flujos de la shell

    * Cómo reemplazar "os.system()"

    * Cómo reemplazar la familia "os.spawn"

    * Cómo reemplazar "os.popen()", "os.popen2()", "os.popen3()"

    * Replacing functions from the "popen2" module

  * Funciones de llamada a la shell de retrocompatibilidad

    * "getstatusoutput()"

    * "getoutput()"

  * Notas

    * Cómo convertir una secuencia de argumentos a una cadena en
      Windows

    * Deshabilitar el uso de "vfork()" o "posix_spawn()"

* "sched" --- Event scheduler

  * "scheduler"

  * Objetos de "Scheduler"

    * "enterabs()"

    * "enter()"

    * "cancel()"

    * "empty()"

    * "run()"

    * "queue"

* "queue" --- A synchronized queue class

  * "Queue"

  * "LifoQueue"

  * "PriorityQueue"

  * "SimpleQueue"

  * "Empty"

  * "Full"

  * "ShutDown"

  * Objetos de la cola

    * "qsize()"

    * "empty()"

    * "full()"

    * "put()"

    * "put_nowait()"

    * "get()"

    * "get_nowait()"

    * "task_done()"

    * "join()"

    * Terminating queues

      * "shutdown()"

  * Objetos de cola simple

    * "qsize()"

    * "empty()"

    * "put()"

    * "put_nowait()"

    * "get()"

    * "get_nowait()"

* "contextvars" --- Context Variables

  * variables de contexto

    * "ContextVar"

      * "name"

      * "get()"

      * "set()"

      * "reset()"

    * "Token"

      * "var"

      * "old_value"

      * "MISSING"

  * Gestión de contexto manual

    * "copy_context()"

    * "Context"

      * "run()"

      * "copy()"

      * "get()"

      * "keys()"

      * "values()"

      * "items()"

  * Soporte asyncio

He aquí módulos de apoyo para algunos de los servicios mencionados:

* "_thread" --- Low-level threading API

  * "error"

  * "LockType"

  * "start_new_thread()"

  * "interrupt_main()"

  * "exit()"

  * "allocate_lock()"

  * "get_ident()"

  * "get_native_id()"

  * "stack_size()"

  * "TIMEOUT_MAX"

  * "acquire()"

  * "release()"

  * "locked()"
