Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Threads
Nuno Ferreira Neves
Faculdade de Ciências de Universidade de Lisboa
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Objetivos da aula
• Introduzir a noção
de thread – uma unidade básica de utilização
do CPU
• Discutir os benefícios
e os
problemas
da programação
multithreaded
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Bibliografia
• [Silberchatz2014], Capítulo 4
NOTA
Os acetatos que se seguem não substituem a bibliografia aqui referida,
e deverão por isso ser vistos apenas como um
complemento
para o
estudo da matéria
.
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Definição
• A thread é uma
unidade básica
de utilização do CPU
• Cada thread tem de forma
exclusiva
– thread id, program counter, valores dos registos do CPU e pilha
• As várias threads de um processo
partilham
– secção de dados, secção de texto
(código) e outros recursos do SO como ficheiros e sinais
• Se um processo tem várias threads (multithreading) pode efetuar
várias tarefas
simultaneamente
, como por exemplo
– Browser com uma thread a mostrar texto e imagens e outra a fazer
download de dados
– Processador de texto com uma thread para mostrar imagem, outra para
interagir com utilizador e ainda outra para verificar se há erros gramaticais Fonte da imagem: [Silberschatz2014]
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Benefícios
• Porquê criar uma thread e não um novo processo?
– razões de desempenho(criar processo demora + tempo e é + “pesado”) e eficiência(processo necessita de + recursos)
• Vantagens relacionadas
– Responsividade: o programa continua a correr mesmo que alguma das tarefas estejam bloqueadas/lenta,permitindo que se mantenha interacção com o utilizador – Partilha de recursos: as técnicas de comunicação entre processos (memória partilhada, troca de mensagens) têm de ser criadas explicitamente, mas as threads partilham as variáveis globais, facilitando a comunicação – Economia: as threads são mais “leves”, sendo mais económico criar novas threads e mudar de contexto entre threads – Escalabilidade: em sistemas multiprocessador, várias threads podem estar a correr simultaneamente Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Programação multicore
• Sistema multicore: sistemas com
vários CPUs
(cores) num único chip
• Nestes sistemas as threads podem correr em
paralelo
…
• …o que traz imensos
desafios
para os
programadores
– Como dividir as tarefas? – Como balancear o trabalho? – Como distribuir/dividir os dados? – Como sincronizar as tarefas? – Como fazer o teste e debugging? Fonte da imagem: [Silberschatz2014]Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Lei de Amdahl
• Como a maior parte dos programas têm componentes sequenciaise componentes paralelizáveis, então:
O ganho em performancede um programa que use múltiplos processadores é
limitado pela fração do programa que é sequencial
– A Lei de Amdahl, numérica e graficamente:
• Exemplo:
– Programa demora 20 horas a correr num computador com apenas um core. Tarefa sequencial demora uma hora (5% sequencial).
– Por mais cores que tenhamos, precisamos de pelo menos 1 hora para terminar o trabalho. A melhoria nunca será maior do que 20x!
Fonte da imagem: [Wiki]
N S S speedup 1 1 S: fração sequencial N: número de processadores Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Tipos de threads
• Threads de nível utilizador
– geridas por bibliotecas de nível utilizador – Principais exemplos: POSIX Pthreads, Win32 threads, Java threads• Threads do kernel
– geridas pelo sistema operativo – Praticamente todos os sistemas atuais têm destas threads (Windows, Linux, Mac OS X, etc.)• Os modelos multithreading
relacionam as threads nível
utilizador com as threads do kernel
– muitas‐para‐uma (many‐to‐one) – uma‐para‐uma (one‐to‐one)
– muitas‐para‐muitas (many‐to‐many)
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Modelo many‐to‐one
• Gestão feita por biblioteca em
espaço utilizador
– pouco comum atualmente• Vantagens
– eficiênciana gestão das threads• por ser feita em user space (espaço
utilizador)
• Desvantagens
– processo pode bloquearse uma
thread faz uma chamada de sistema
bloqueante
– multiplas threads não podem correr
em paralelonum sistema multiprocessador/multicore Fonte da imagem: [Silberschatz2014] Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Modelo one‐to‐one
• Vantagens
– uma thread pode correr quando outra está bloqueada
– várias threads correm em paralelonum sistema multiprocessador/multicore
• Desvantagens
– o overhead de criar threads no kernel pode afetar o desempenho da aplicação
• por isso normalmente restringe‐seo número de threads permitidas no sistema
• Por exemplo, o Windows e o Linux implementam este modelo
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Modelo many‐to‐many
• Multiplexam‐se threads de nível
utilizador num número
inferior ou
igual
de threads do kernel
• Maior flexibilidade
– junta vantagens do modelo many‐to‐ many... • programador pode criar as threadsque quiser ... com vantagens do modelo one‐to‐one • uma thread pode correr quando outra está bloqueada • múltiplas threads podem correr em paralelonum sistema multiprocessador Fonte da imagem: [Silberschatz2014] Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Modelo two‐level
• “Dois em um”
– modelo many‐to‐many como base mas permite que algumas user threads estejam ligadas a uma só kernel thread (one‐to‐one)• Este modelo era usado pelo Solaris
– mas a partir da versão 9 passou para o one‐to‐one
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Bibliotecas de threads
• As bibliotecas de threads oferecem uma API
para os
programadores criarem e gerirem threads
– podem ser implementadas integralmente em espaço utilizador ou como
uma biblioteca gerida pelo kernel
• Exemplos
– Pthreads
• o standard POSIX especifica o comportamento, mas a concretização fica a
cargo da biblioteca
• pode ser implementada a nível utilizador ou nível kernel • comum em sistemas Unix (Linux, Mac OS X, Solaris)
– Java Threads
• geridas pela JVM e são tipicamente implementada usando a biblioteca de
threads oferecida pelo SO “anfitrião”
• podem ser concretizadas estendendo a classe Threadou implementando a
interface Runnable
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Python API: exemplo
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Threading implícito
• Com o crescimento do processamento multicore, está a tornar‐
se muito popular programar aplicações com
centenas
ou
milhares
de threads
– tornando‐se muito complicado para o programador garantirque o programa funciona corretamente
• A alternativa
é a criação e gestão das threads pelos
compiladores
e
bibliotecas
de run‐time, em vez de ser uma
tarefa dos programadores
• Vamos explorar três métodos
– Thread Pools – OpenMP – Grand Central Dispatch Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Thread pools
• Exemplo motivador: servidor que tem de servir muitos clientes
– Solução “básica”: uma thread por cliente – Problemas desta solução: • tempo de criação da thread (mais rápido do que um novo processo, mas ainda assim demora tempo) e depois a sua destruição (qdo acaba de executar)• e se forem mesmo MUITOSclientes?
• Para resolver estes dois problemas pode criar‐se uma thread
pool
– cria‐se logo de início um número limitado de threads que ficam à espera (numa pool) de trabalhopara fazer
• melhor performance(threads já estão criadas quando surgem os pedidos)
• melhor gestãode recursos (podemos limitar o número máximo de threads
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
OpenMP
• Conjunto de diretivas de compilador
de
suporte
à
programação paralela
– API para C, C++, FORTRAN• Permite identificar regiões paralelas
– isto é, blocos de código que podemcorrer em paralelo
• A diretiva:
#pragma omp parallel
cria várias threads (tantas quanto o
número de cores disponível)
• Existem outras diretivas, permitindo
por exemplo que o trabalho de um
loop for seja dividido pelas threads
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015Grand Central Dispatch
• Semelhante ao openMP, mas da Apple
, para Mac OS X e iOS
– suporta C e C++• Também permite a identificação de blocos paralelos
– para gerir o threading• No GCD um bloco
é delimitado por
“^{ }”
ˆ{ printf("I am a block"); }
• Os blocos são colocados numa fila
e são atribuídos a uma
thread (de uma pool) quando são removidos dessa fila
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Semânticas do fork() e exec()
• Como funciona o fork() e o exec() no caso de várias threads?
• O exec() funciona como no caso de thread única
– o programa passado como argumento do exec()substituitodo o processo, incluindo todas as suas threads
• O fork() duplica apenas
a thread que o invoca ou
todas
as
threads do processo?
– a melhor escolha dependeda aplicação, existindo alguns UNIX que suportam duas variantes do fork():
1. se o exec() é invocado logo após o fork() é desnecessárioduplicar todas as threads
• dado que serão substituídas pelo programa passado ao exec()
2. caso contrário, o fork() deve duplicar todasas threads
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Cancelamento de threads
• Exemplos
– quando se carrega no botão “stop”, num browser da Web, todas as threads devem ser canceladas• Opções de cancelamento
– assíncrono: termina thread “alvo” imediatamente
– diferido: dá‐se tempoà thread “alvo” para cancelar
• a thread “alvo” deve determinar periodicamente se deve terminar • o tempo concedido pode ser usado para terminar “corretamente”
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Manipulação de sinais
• Os sinais são usados em sistemas UNIX para notificar
os
processos de que ocorreu um
evento
– sinal é geradoé enviadoao processo, e o processo tratao sinal
• Tipos de sinais
1. síncrono: sinal entregue ao processo que o gerou
• e.g., divisão por zero, acesso ilegal à memória
2. assíncrono: sinal entregue ao processo devido a um evento externo
• e.g., <ctrl>+<c>, disparo de alarme
• Tratar do sinal:
1) default signal handler; 2) signal handler do utilizador• E se o processo tiver múltiplas threads?
– envia‐se o sinal apenas para a thread a que o sinal se aplica?
– ou para todas? Ou apenas para algumas?
• Resposta: depende
do sinal
– sinal síncrono deve ser entregue à thread que o gerou
– com sinais assíncronos a opção é menos clara.
• alguns, como <ctrl>+<c>, devem ser entregues a todas as threads
Fernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015
Armazenamento local de thread
• As várias threads de um processo partilham
a secção de dados
– vantagem importante, porque facilita comunicação
• E têm pilha para os seus dados locais temporários
• Mas há dados que podem ser locais (específicos
de uma só
thread) mas terem carácter permanente
– isto é, devem estar disponíveis não só numa invocação de uma função, mas entre invocações – imagine uma thread que quer manter o seu identificador entre chamadas à sua execução – as bibliotecas de threads normalmente oferecem este tipo de suporteFernando Ramos, Nuno Neves, Sistemas Operativos, 2014‐2015