17.9. :mod:--- API de segmentação de baixo nível
************************************************

======================================================================

Este módulo fornece primitivos de baixo nível para trabalhar com
vários tópicos (também chamados: dfn: *light-weight processes* ou:
dfn:` tasks`) --- vários tópicos de controle compartilhando seu espaço
de dados global. Para sincronização, bloqueios simples (também
chamados de: dfn: *mutexes* ou: dfn:` binary semaphores`) são
fornecidos. O módulo: mod: *threading* fornece uma API de segmentação
mais fácil de usar e de nível mais alto, construída sobre este módulo.

O módulo é opcional. Ele é suportado no Windows, Linux, SGI IRIX,
Solaris 2.x, bem como em sistemas que possuem uma implementação de
filamento POSIX (a.k.a. "pthread"). Para sistemas que faltam o módulo:
mod: *_thread*, o módulo: mod:` _dummy_thread` está disponível. Ele
duplica a interface deste módulo e pode ser usado como substituto
imediato.

Define as seguintes constantes e funções:

exception _thread.error

   Gerado em erros específicos de segmento.

   Alterado na versão 3.3: Este é agora um sinônimo do built-in: exc:
   *RuntimeError*.

_thread.LockType

   Este é o tipo de objetos de bloqueio.

_thread.start_new_thread(function, args[, kwargs])

   Inicie um novo encadeamento e retorne seu identificador. O
   encadeamento executa a função * function * com a lista de
   argumentos * args * (que deve ser uma tupla). O argumento opcional
   * kwargs * especifica um dicionário de argumentos de palavras-
   chave. Quando a função retorna, o segmento sai silenciosamente.
   Quando a função termina com uma exceção não tratada, um
   rastreamento de pilha é impresso e, em seguida, o segmento sai (mas
   outros segmentos continuam a ser executados).

_thread.interrupt_main()

   Raise a "KeyboardInterrupt" exception in the main thread.  A
   subthread can use this function to interrupt the main thread.

_thread.exit()

   Gera a exceção:exc:*SystemExit*.  Quando não for detectada, o
   thread sairá silenciosamente.

_thread.allocate_lock()

   Retorna um novo objeto de bloqueio. Métodos de bloqueio são
   descritos abaixo. O bloqueio é desativado inicialmente.

_thread.get_ident()

   Retorna o 'identificador de thread' do thread atual. Este é um
   número inteiro diferente de zero. Seu valor não tem significado
   direto; pretende-se que seja um cookie mágico para ser usado, por
   exemplo, para indexar um dicionário de dados específicos do thread.
   identificadores de thread podem ser reciclados quando um thread sai
   e outro é criado.

_thread.stack_size([size])

   Return the thread stack size used when creating new threads.  The
   optional *size* argument specifies the stack size to be used for
   subsequently created threads, and must be 0 (use platform or
   configured default) or a positive integer value of at least 32,768
   (32 KiB). If *size* is not specified, 0 is used.  If changing the
   thread stack size is unsupported, a "RuntimeError" is raised.  If
   the specified stack size is invalid, a "ValueError" is raised and
   the stack size is unmodified.  32 KiB is currently the minimum
   supported stack size value to guarantee sufficient stack space for
   the interpreter itself.  Note that some platforms may have
   particular restrictions on values for the stack size, such as
   requiring a minimum stack size > 32 KiB or requiring allocation in
   multiples of the system memory page size - platform documentation
   should be referred to for more information (4 KiB pages are common;
   using multiples of 4096 for the stack size is the suggested
   approach in the absence of more specific information).
   Availability: Windows, systems with POSIX threads.

_thread.TIMEOUT_MAX

   O valor máximo permitido para o parâmetro * timeout * de :meth:
   *Lock.acquire*. A especificação de um tempo limite maior que esse
   valor gerará um: exc: *OverflowError*.

   Novo na versão 3.2.

Os objetos de bloqueio têm os seguintes métodos:

lock.acquire(waitflag=1, timeout=-1)

   Sem nenhum argumento opcional, esse método adquire o bloqueio
   incondicionalmente, se necessário, aguardando até que seja liberado
   por outro encadeamento (apenas um encadeamento por vez pode
   adquirir um bloqueio - esse é o motivo da sua existência).

   Se o argumento inteiro *waitflag* estiver presente, a ação
   dependerá do seu valor: se for zero, o bloqueio será adquirido
   apenas se puder ser adquirido imediatamente sem aguardar, enquanto
   se for diferente de zero, o bloqueio será adquirido
   incondicionalmente, conforme acima.

   Se o argumento de ponto flutuante *timeout* estiver presente e
   positivo, ele especificará o tempo máximo de espera em segundos
   antes de retornar. Um argumento negativo *timeout* especifica uma
   espera ilimitada. Você não pode especificar um *timeout* se
   *waitflag* for zero.

   O valor de retorno é "True" se o bloqueio for adquirido com
   sucesso, se não "False".

   Alterado na versão 3.2: O parâmetro *timeout* é novo.

   Alterado na versão 3.2: As aquisições de bloqueio agora podem ser
   interrompidas por sinais no POSIX.

lock.release()

   Libera o bloqueio. O bloqueio deve ter sido adquirido
   anteriormente, mas não necessariamente pela mesma thread.

lock.locked()

   Retorna o status do bloqueio: "True" se tiver sido adquirido por
   alguma thread, "False" se não for o caso.

Além desses métodos, os objetos de bloqueio também podem ser usados
através da instrução "with", por exemplo:

   import _thread

   a_lock = _thread.allocate_lock()

   with a_lock:
       print("a_lock is locked while this executes")

**Ressalvas:**

* Threads interagem estranhamente com interrupções: a exceção
  "KeyboardInterrupt" será recebida por uma thread arbitrário. (Quando
  o módulo "signal" está disponível, as interrupções sempre vão para a
  thread principal.)

* Chamar "sys.exit()" ou levantar a exceção "SystemExit" é o
  equivalente a chamar "_thread.exit()".

* Não é possível interromper o método "acquire()" em um bloqueio --- a
  exceção "KeyboardInterrupt" ocorrerá após o bloqueio ter sido
  adquirido.

* Quando a thread principal se encerra, é definido pelo sistema se as
  outras threads sobrevivem. Na maioria dos sistemas, elas são
  eliminadas sem executar cláusulas "try" ... "finally" ou executar
  destruidores de objetos.

* Quando a thread principal é encerrada, ela não realiza nenhuma
  limpeza usual (exceto que as cláusulas "try" ... "finally" são
  honradas) e os arquivos de E/S padrão não são liberados.
