Sie sind auf Seite 1von 57

Sistemas Operacionais com Java

Threads

• Visão geral
• Modelos multithreads
• Aspectos do uso de threads
• Pthreads
• Threads no Windows XP
• Threads no Linux
• Threads em Java

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads
• De forma geral, cada fluxo de execução do sistema, seja
associado a um processo ou no interior do núcleo, é
denominado thread
• Uma Thread (ou processo leve) é uma unidade básica
da utilização da CPU; ela consiste em:
– contador de programa
– conjunto de registradores
– espaço de pilha

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads
• Uma Thread compartilha com suas Threads afins:
– sua seção de código
– sua seção de dados

– seus recursos de sistema operacional coletivamente


conhecidos como uma tarefa

• Um processo tradicional, ou pesado, é igual a uma


tarefa com uma única Thread

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Processos e Threads

um processo um processo
uma thread múltiplas threads

múltiplos processos múltiplos processos


uma thread por processo múltiplas threads po process

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Processos com Thread Única


e Múltithread

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Processos com Thread Única


e Múltithread
Multithreaded
Single-Threaded Process Model
Process Model

Thread Thread Thread

Thread Thread Thread


Control Control Control
Process User Block Block Block
Control Stack
Block

Process
Control User User User
Block Stack Stack Stack
User Kernel
Address Stack
Space

User
Address Kernel Kernel Kernel
Space Stack Stack Stack

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads

• Possui um estado de execução (running, ready, etc.)


• Possui um contexto, salvo quando não está executando
• Possui uma pilha de execução
• Possui algum armazenamento estático, por thread, para
variáveis locais
• Possui acesso a memória e recursos do próprio processo
– compartilhado por todas as threads do processo

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads

• Em uma tarefa com múltiplas threads, enquanto uma


thread servidora está bloqueada e esperando, uma
segunda thread da mesma tarefa pode ser executada
– A cooperação de múltiplas threads na mesma tarefa
confere maior throughput e melhor desempenho
– As aplicações que precisam compartilhar um buffer
comum (ou seja, produtor-consumidor) tiram proveito
da utilização da thread

• As Threads fornecem um mecanismo para permitir que


processos seqüenciais façam chamadas de sistema
bloqueantes ao mesmo tempo em que obtêm
paralelismo

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Vantagens
• Responsividade: programa continua mesmo que parte
dele esteja bloqueada. Exemplo: navegador Web
multithread pode interagir com o usuário enquanto
carrega imagens

• Compartilhamento de recursos

• Utilização de arquiteturas multiprocessadas

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Vantagens

• Sua criação consome menos tempo que a criação de um


processo
• Menos tempo para terminá-la
• Intercalação entre threads do mesmo processo consomem
pouco tempo
• Já que threads do mesmo processo compartilham memória e
arquivos, comunicação entre elas não invocam o kernel
Sistemas Operacionais com Java

Threads

• Suspender um processo implica em suspender todas as


threads do processo
• Terminar um processo, termina todas as threads do
processo
• Duas categorias de implementação:
– user-level threads
– kernel-level threads
Sistemas Operacionais com Java

Threads

• Threads executando dentro de um processo são


chamados de threads de usuário (user-level threads
ou simplesmente user threads). Cada thread de
usuário corresponde a uma tarefa a ser executada.

• Por sua vez, os fluxos de execução reconhecidos e


gerenciados pelo núcleo do sistema operacional são
chamados de threads de núcleo (kernel-level threads
ou kernel threads).

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads de Usuário
• Sem poder contar com o suporte do sistema operacional
para a criação de múltiplos threads, os desenvolvedores
contornaram o problema construindo bibliotecas para
gerenciar threads dentro de cada processo, sem o
envolvimento do núcleo.

• Gerenciadas por biblioteca de threads no nível do usuário

• Três bibliotecas de threads principais:


– POSIX Pthreads
– Threads Java
– Threads Win32

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads de kernel

• Suportado pelo kernel

• Exemplos
– Windows XP/2000
– Solaris
– Linux
– Tru64 UNIX
– Mac OS X

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Modelos Multithreads

• Muitos-para-um

• Um-para-um

• Muitos-para-muitos

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads N:1 (Muitos-para-Um)

• Usando bibliotecas para gerenciar threads dentro de


cada processo, sem o envolvimento do núcleo, uma
aplicação pode lançar vários threads conforme sua
necessidade, mas o núcleo do sistema irá sempre
perceber (e gerenciar) apenas um fluxo de execução
naquele processo.
• Por essa razão, esta forma de implementação de
threads é nomeada Modelo de Threads N:1: N threads
no processo, mapeados em um único thread de
núcleo.

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Muitos-para-Um
• Muitas threads no nível do usuário associadas a uma única
thread de kernel

• Exemplos
– Solaris Green Threads
– GNU Portable Threads

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Um-para-Um
• Cada thread do usuário associada a uma thread de kernel
• O modelo de threads 1:1 é adequado para a maioria da
situações e atende bem às necessidades das aplicações
interativas e servidores de rede. No entanto, é pouco
escalável: a criação de um grande número de threads impõe
um carga significativa ao núcleo do sistema, inviabilizando
aplicações com muitas tarefas (como grandes servidores Web
e simulações de grande porte).
• Exemplos
• Windows NT/XP/2000
• Linux
• Solaris 9 e acima

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Modelo Um-para-Um

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Muitos-para-Muitos

• Permite que muitas threads no nível do usuário sejam


associadas a muitas threads no nível do kernel

• Permite que o sistema operacional crie um número


suficiente de threads de kernel

• Exemplos
– Solaris antes da versão 9
– Windows NT/2000 com o pacote ThreadFiber

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Modelo em Dois Níveis (N:M)

• Semelhante ao modelo M:M, exceto que permite que


uma thread do usuário seja associada a um número
menor ou igual de threads do kernel

• Exemplos
– IRIX
– HP-UX
– Tru64 UNIX
– Solaris até a versão 8

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Modelo em Dois Níveis

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Comparativo entre Modelos

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Suporte a Threads no Solaris 2

• O Solaris 2 é uma versão do UNIX com suporte para


User-Level Threads e Kernel-Level Threads,
multiprocessamento simétrico e escalonamento em
tempo real

• LWP – nível intermediário entre as Threads no nível


do usuário e as Threads no nível do Kernel

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Suporte a Threads no Solaris 2

• Necessidades de recurso dos tipos Threads:


– Threads de Kernel: pequena estrutura de dados e
uma pilha; a troca de Threads não exige alterar as
informações de acesso à memória —
relativamente rápido
– LWP: PCB com dados de registrador, contabilidade
e informações de memória; a troca entre LWPs é
relativamente lenta
– Threads no nível do usuário: necessita apenas de
pilha e contador de programa; nenhum
envolvimento de núcleo significa rapidez de troca.
O núcleo vê apenas os LWPs que admitem
threads no nível do usuário

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads do Solaris 2

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Aspectos do Uso de Threads

• Semântica das chamadas de sistema fork() e exec()

• Cancelamento da thread

• Tratamento de sinais

• Bancos de threads

• Dados específicos da thread

• Ativações de escalonador

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Semântica do fork() e exec()

• fork() duplica apenas a thread que o chama ou todas


as threads?

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Cancelamento da Thread

• Termina uma thread antes que tenha sido completada

• Dois métodos gerais:


– Cancelamento assíncrono – termina a thread-alvo
imediatamente
– Cancelamento adiado – permite que a thread-alvo
verifique periodicamente se deve ser cancelada

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Tratamento de Sinais

• Sinais são usados nos sistemas UNIX para notificar


um processo de que um evento específico ocorreu

• Um tratador de sinal é usado para processar sinais


1. Um sinal é gerado por um evento em particular
2. O sinal é entregue a um processo
3. O sinal é tratado

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Tratamento de Sinais

• Opções:
– Entregar o sinal a thread a que ele se aplica
– Entregar o sinal a cada thread no processo
– Entregar o sinal a certas threads no processo
– Atribuir uma thread específica para receber todos
os sinais para o processo

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Bancos de Threads

• Uma série de threads são criadas em um banco, onde


esperam para atuar
• Vantagens:
– Em geral, é um pouco mais rápido atender a uma
requisição com uma thread existente do que criar
uma nova thread
– Permitem que o número de threads da(s) aplicação
(ções) seja limitado ao tamanho do banco

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Dados Específicos da Thread

• Cada thread pode ter sua própria cópia dos dados

• Útil quando não é necessário ter controle sobre o


processo de criação de thread (isto é, quando um banco
de thread está em uso)

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Ativações do Escalonador

• Os modelos M:M e de dois níveis necessitam de


comunicação para manter o número apropriado de
threads de kernel alocadas para a aplicação

• As ativações do escalonador fornecem upcalls — um


mecanismo de comunicação do kernel para a
biblioteca de threads

• Essa comunicação permite que uma aplicação


mantenha o número correto de threads de kernel

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Pthreads

• Uma API do padrão POSIX (IEEE 1003.1c) para a


criação e sincronismo de thread

• A API especifica o comportamento da biblioteca de


threads; a implementação cabe ao desenvolvimento
da biblioteca

• Comuns nos sistemas operacionais UNIX (Solaris,


Linux, Mac OS X)

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Pthreads
int sum; /* esses dados são compartilhados pela(s) Thread(s) */
void *runner(void *param); /* a thread*/

Int main(int argc, char **argv)


{
pthread_t tid; /* o identificador da Thread */
pthread_attr_t attr; /* conjunto de atributos para a Thread */

pthread_attr_init(&attr); /* obtém os atributos padrão */


pthread_create(&tid,&attr,runner,argv[1]); /* cria a thread */
/* agora espera que o fluxo termine */
pthread_join(tid,NULL);
printf(“soma = %d\n",sum);
exit(0)
}
void *runner(void *param)
{
int upper = atoi(param);
int i;

sum = 0;
if (upper > 0) {
for (i = 1; i <= upper; i++)
sum += i;
}
pthread_exit(0);
}
Silberschatz, Galvin e Gagne (c) 2003
Sistemas Operacionais com Java

Threads no Windows XP

• Implementa o mapeamento um-para-um

• Cada thread contém


– Uma ID de thread
– Um conjunto de registradores
– Pilhas do usuário e do kernel separadas
– Uma área de armazenamento privada

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads no Windows XP

• O conjunto de registradores, as pilhas e a área de


armazenamento privada são conhecidos como o
contexto das threads

• As principais estruturas de dados de uma thread


incluem:
– ETHREAD (bloco de thread do executivo)
– KTHREAD (bloco de thread do kernel)
– TEB (bloco de ambiente do thread)

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Estrutura Dados Threads Windows XP


Sistemas Operacionais com Java

Programa C API Win32


Sistemas Operacionais com Java

Programa C API Win32


Sistemas Operacionais com Java

Threads no Linux

• O Linux refere-se a elas como tarefas, em vez de


threads

• A criação de thread é feita através da chamada de


sistema clone()

• clone() permite que uma tarefa filha compartilhe o


espaço de endereços da tarefa pai (o processo)

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Threads em Java

• São gerenciadas pela JVM

• Podem ser criadas através de:


– Extensão da classe Thread
– Implementação da interface Runnable

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Estendendo a classe Thread


class Worker1 extends Thread
{
public void run() {
System.out.println(“Eu sou a thread trabalhadora");
}
}

public class First


{
public static void main(String args[]) {
Worker1 runner = new Worker1();
runner.start();
System.out.println(“Eu sou a Thread principal");
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

A interface Runnable
public interface Runnable
{
public abstract void run();
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Implementando a interface Runnable


class Worker2 implements Runnable
{
public void run() {
System.out.println(“Eu sou a Thread trabalhadora ");
}
}
public class Second
{
public static void main(String args[]) {
Runnable runner = new Worker2();
Thread thrd = new Thread(runner);
thrd.start();
System.out.println(“Eu sou a thread principal");
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Estados da thread

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Aguardando o término das threads


class JoinableWorker implements Runnable
{
public void run() {
System.out.println(“trabalhador trabalhando");
}
}

public class JoinExample


{
public static void main(String[] args) {
Thread task = new Thread(new JoinableWorker());
task.start();

try { task.join(); }
catch (InterruptedException ie) { }

System.out.println(“Terminado");
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Cancelamento da Thread
Thread thrd = new Thread (new InterruptibleThread());
Thrd.start();

...

// agora o interrompe
Thrd.interrupt();

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Cancelamento da Thread
public class InterruptibleThread implements Runnable
{
public void run() {
while (true) {
/*
* faz algum trabalho por um tempo
*/

if (Thread.currentThread().isInterrupted()) {
System.out.println(“Fui interrompida! ");
break;
}
}

// limpa e termina
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Dados Específicos da Thread


class Service
{
private static ThreadLocal errorCode = new ThreadLocal();

public static void transaction() {


try {
/**
* alguma operação onde pode ocorrer erro
*/
}
catch (Exception e) {
errorCode.set(e);
}
}

/**
* apanha código de erro para esta transação
*/
public static Object getErrorCode() {
return errorCode.get();
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Dados específicos da thread


class Worker implements Runnable
{
private static Service provider;

public void run() {


provider.transaction();
System.out.println(provider.getErrorCode());
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Programa com threads Java


Sistemas Operacionais com Java

Programa com threads Java (Cont.)


Sistemas Operacionais com Java

Problema Produtor-Consumidor
public class Factory
{
public Factory() {
// Primeiro cria o buffer de mensagens
Channel mailBox = new MessageQueue();

// Agora cria os threads produtor e consumidor


Thread producerThread = new Thread(new Producer(mailBox));
Thread consumerThread = new Thread(new Consumer(mailBox));

producerThread.start();
consumerThread.start();
}

public static void main(String args[]) {


Factory server = new Factory();
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Thread Produtor
class Producer implements Runnable
{
private Channel mbox;

public Producer(Channel mbox) {


this.mbox = mbox;
}

public void run() {


Date message;

while (true) {
SleepUtilities.nap();
message = new Date();
System.out.println("Produtor produziu " + message);

// produz um item e o inclui no buffer


mbox.send(message);
}
}
}

Silberschatz, Galvin e Gagne (c) 2003


Sistemas Operacionais com Java

Thread Consumidor
class Consumer implements Runnable
{
private Channel mbox;

public Consumer(Channel mbox) {


this.mbox = mbox;
}
public void run() {
Date message;

while (true) {
SleepUtilities.nap();
// consome um item do buffer
System.out.println("Consumidor deseja consumir.");

message = (Date)mbox.receive();
if (message != null)
System.out.println("Consumer consumed "+ message);
}
}
}

Silberschatz, Galvin e Gagne (c) 2003

Das könnte Ihnen auch gefallen