Threads no Multiplus/Mulplix Adriano Cruz ©2003 NCE e IM/UFRJ [email protected].
Transcript of Threads no Multiplus/Mulplix Adriano Cruz ©2003 NCE e IM/UFRJ [email protected].
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 2
Sumário
O Ambiente Multiplus/Mulplix O Ambiente de Programação Interface para Usuário Exemplos
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 3
Multiplus
Multiplus é um processador de alto desempenho com memória compartilhada, fisicamente distribuída.
Arquitetura modular prevê até 1024 processadores e 32 Gbytes de memória global.
Nós de processamento com Sparc
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 4
Arquitetura do Multiplus
Redede
Interconexã oMult iestá gio
Interfa cede
Rede
Tra nsf. P/ bloco
Instruções/Da dos
NPNP
Interfa cede
Rede
Tra nsf. P/ bloco
Instruções/Da dos
NPNP
Processa dorde E/S
Processa dorde E/S
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 5
Características do Multiplus 1
Até 4 nós de processamento (NPs) formam um cluster
Memória com tempo de acesso não uniforme (NUMA)– Acesso ao cache local– Acesso à memória local – Acesso à memória em um NP do cluster– Acesso à memória em outro cluster
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 6
Características do Multiplus 2
Entrada e Saída distribuída, cada cluster tem seu processador de E/S
Consistência de cache entre NPs– Intra-cluster é baseado em hardware– Dados modificáveis somente podem ser
cacheados dentro do cluster– Inter-cluster em implementação
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 7
Mulplix 1
Unix-like Aplicação paralela é constituída de um
processo composto por uma ou mais threads
Compartilham recursos do processo– Páginas de memória, Descritores de
arquivo, etc. Variáveis globais são vistas por todas
threads
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 8
Mulplix 2
Processos possuem uma estrutura em árvore m-ária contendo informações das threads pertencentes ao processo
Em cada nível da árvore podem ser definidas 128 threads ao mesmo tempo
Cada processo possui pelo menos uma thread principal
Identificadores vão de 0 (thread principal) até a nthreads - 1
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 9
Ambiente de Programação
Cada thread é mapeada em uma função Está função não retorna valor (tipo void) e
recebe apenas dois parâmetros– Conjunto de argumentos– Número indicando a ordem da thread
Cada thread possui uma área de memória privada, a pilha (variáveis locais e parâmetros)
Cada thread possui uma área de memória compartilhada (variáveis globais do processo)
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 10
Criação de threads
Existem duas formas de criação de threads
– Assíncrona: A thread continua normalmente após a criação dos descendentes
– Síncrona: A thread só continua a execução após o término dos descendentes
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 11
Término de Execução
Uma thread termina sua execução de três formas:– Alcança a última instrução de seu código– Executa um comando de término– Sinalizada por uma outra thread indicando
que deve terminar Quando uma thread termina todas as
suas descendentes são automaticamente finalizadas
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 12
Outras Características
Semáforos do tipo Mutex para exclusão mútua
– Mulplix provê a possibilidade de mais de uma thread entrar em uma região crítica
Semáforos do tipo event para condicionar execuções à ocorrências de eventos
Alocação dinâmica de memória
– Alocação privada no segmento de dados da thread
– Alocação compartilhada no segmento de dados do processo
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 13
Criação de threads síncrona 1 int info thr_spawns (int nthreads, void (*func) (), int arg, int *mapping)
info – retorna o número de threads efetivamente criadas. Em caso de erro retorna um valor negativo
nthreads – número de threads a serem criadas func – nome da função que será executada como
uma nova thread arg – parâmetro passado para a thread mapping – vetor com nthreads posições. Indica a
qual processador a thread deve ser associada. Caso seja nulo o sistema irá alocar da melhor maneira possível.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 14
Criação de threads síncrona 2
A função func deve possuir o seguinte protótipo
void func (int arg, int ordem);
arg – parâmetro passado à thread através da chamada thr_spawns
ordem – indica a ordem da thread quando da criação de um grupo de threads.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 15
Exemplo de criação síncrona
#include<stdio.h>#include<mulplix.h>
void ola (int arg, int ord){printf ("ola: Eu sou a thread %d\n", ord);printf ("ola: Recebi %d\n", arg);}
void main ( void ){printf("main: Eu sou a thread principal\n");thr_spawns(3, ola, 1, NULL);printf("main: Criei tres filhas\n");}
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 16
Diagrama de execução
main: Eu sou a thread principal
thr_spawns
Ola: Eu sou a thread 0Ola: Recebi 1
Ola: Eu sou a thread 1Ola: Recebi 1
Ola: Eu sou a thread 2Ola: Recebi 1
main: Criei tres filhas
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 17
Criação de threads assíncrona 2
A função é semelhante a que cria threads síncronas.
int info thr_spawn (int nthreads, void (*func) (), int arg, int *mapping)
Lembrar que neste caso a thread criadora continua independentemente, e portanto se ela terminar as suas descendentes também terminam.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 18
thr_id int tid = thr_id (void); Retorna a identificação (tid) de uma
thread. A thread principal sempre tem tid igual
a 0
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 19
thr_term int info = thr_term (void); Termina a execução da thread. Todas as descendentes da thread que
fez a chamada são finalizadas também. info - se a chamada for bem sucedida
retorna o valor 0, em caso de erro retorna um valor negativo.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 20
thr_kill int info= thr_kill (int tid); Termina a execução de uma thread e
todas suas descendentes. info - se a chamada for bem sucedida
retorna o valor 0, em caso de erro retorna um valor negativo.
tid - identificação da thread a ser finalizada
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 21
Mutex 1
O mutex do Mulplix é funcionalmente idêntico ao semáforo criado por Dijkstra e as rotinas mx_lock e mx_free são correspondentes às operações P e V respectivamente.
Para usar um mutex é necessário criá-lo com uma chamada específica: mx_create
Ao final o mutex deve ser destruído para que os recursos ocupados sejam liberados (mx_delete)
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 22
Mutex 2
Para reservar um recurso associado com um mutex deve-se usar a função mx_lock
Ao final o mutex deve ser destruído para que os recursos ocupados sejam liberados (mx_delete)
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 23
mx_create
Cria um semáforo do tipo mutex, definindo o número de recursos associados:
MUTEX sema=mx_create(int nrecursos); sema – se a chamada for bem sucedida,
retorna um semáforo do tipo mutex. Em caso de erro, retorna um número negativo
nrecursos – número de recursos associados ao mutex. Indica o número de threads que podem acessar a região crítica ao mesmo tempo
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 24
mx_delete
Destrói um semáforo do tipo mutex int info = mx_delete(MUTEX sema); info – se a chamada for bem sucedida,
retorna 0. Em caso de erro, retorna um número negativo
sema – semáforo do tipo mutex a ser destruído. Todas as threads bloqueadas neste semáforo serão liberadas. Todas serão informadas que o semáforo foi destruído através do valor de retorno da rotina mx_lock
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 25
mx_lock
Aloca um recurso associado a um semáforo do tipo mutex
int info = mx_lock(MUTEX sema);
info – se a chamada for bem sucedida, retorna 0. Em caso de erro, retorna um número negativo
sema – semáforo do tipo mutex a ser usado
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 26
mx_lock 1
Se o número de recursos disponíveis for maior que zero, decrementa este valor e permite a thread acessar a região crítica
Caso não haja recursos a thread será suspensa, sendo colocada em uma fila de espera associada ao semáforo.
A thread será ativada quando outra sair da região crítica e liberar um dos recursos.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 27
mx_free
Libera um recurso associado a um semáforo do tipo mutex, ou seja incrementa o número de recursos disponíveis
int info = mx_free(MUTEX sema);
info – se a chamada for bem sucedida, retorna 0. Em caso de erro, retorna um número negativo
sema – semáforo do tipo mutex a ser liberado
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 28
mx_test
Verifica se exite um recurso disponível associado a um semáforo do tipo mutex. Caso exista, aloca este recurso, decrementando o número de recursos disponíveis
Se não houver recurso disponível, retorna da rotina sem bloquear a thread
int info = mx_test(MUTEX sema); info – se a chamada for bem sucedida, retorna
0. Em caso de erro, retorna um número negativo sema – semáforo do tipo mutex a ser liberado
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 29
Exemplo de mutex 1#include<stdio.h>#include<unistd.h>#include<mulplix.h>
int vet1 [3] = {1, 3, 5};int vet2 [3] = {2, 4, 6};int total = 0;
MUTEX sema;
void produto (int arg, int ord){int i;
printf("produto: Eu sou a thread %d\n", ord);mx_lock (sema);total += vet1[ord] * vet2[ord];mx_free (sema);printf("produto: Eu sou a thread %d terminando...\n", ord);}
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 30
Exemplo de mutex 2
void main ( void ){printf("main: Eu sou a thread principal\n");
sema = mx_create (1);
thr_spawns(3, produto, 0, NULL);
mx_delete (sema);
printf("main: O produto interno e %d\n", total);}
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 31
Sincronização por Eventos
Semáforos do tipo evento permitem programação com sincronização temporal.
Através da sinalização e espera por eventos, pode ser estabelecida uma ordem de execução
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 32
ev_create EVENT sema = ev_create (int nsignals, int nwaits);
Cria um semáforo do tipo event, determinando o número de threads que devem participar do evento por sinalização e por espera
sema – se a chamada for bem sucedida, retorna um semáforo do tipo event. Retorna um negativo em caso de erro
nsignals – número de threads que devem sinalizar a sua participação no evento
nwaits – número de threads que irão esperar a ocorrência do evento
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 33
ev_delete int info = ev_delete (EVENT sema); Destrói um semáforo do tipo event sema – semáforo do tipo EVENT a ser destruído.
Todas as thread bloqueadas neste semáforo serão liberadas com a sua destruição. Todas as threads serão informadas de sua destruição através do valor de retorno das rotina ev_wait e ev_swait
info – se a chamada for bem sucedida retorna 0, e um valor negativo em caso de erro.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 34
ev_signal int info = ev_signal (EVENT sema); Sinaliza a participação em um evento sema – semáforo do tipo EVENT info – se a chamada for bem sucedida retorna 0, e
um valor negativo em caso de erro. A rotina ev_signal não bloqueia a execução da
thread. O evento irá ocorrer quando todas as threads
participantes tiverem sinalizado ou esperado a ocorrência do evento.
A ocorrência de um evento causa a liberação de todas a threads esperando por este evento
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 35
ev_wait int info = ev_wait (EVENT sema);
Espera pela ocorrência de um evento
sema – semáforo do tipo EVENT
info – se a chamada for bem sucedida retorna 0, e um valor negativo em caso de erro.
A rotina ev_wait bloqueia a execução da thread até que o evento ocorra.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 36
ev_swait int info = ev_swait (EVENT sema);
Junção das rotinas ev_signal e ev_wait
sema – semáforo do tipo EVENT
info – se a chamada for bem sucedida retorna 0, e um valor negativo em caso de erro.
A thread sinaliza a participação no evento e logo em seguida entra em espera, ficando bloqueada até que o evento ocorra.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 37
Exemplo de evento 1
void main ( void ){int i;printf("main: Eu sou a thread principal\n");filhas = ev_create (2, 1);thr_spawn(2, produto, 0, NULL);vet1[0] *= vet2[0];ev_wait(filhas);for (i = 1; i < 3; i++) total += vet1[i];ev_delete(filhas);printf("main: O produto interno e %d\n", total);}
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 38
Exemplo de evento 1
int vet1 [3] = {1, 3, 5};int vet2 [3] = {2, 4, 6};int total = 0;
EVENT filhas;
void produto (int arg, int ord){int tid;
printf("produto: Eu sou a thread %d\n", ord);tid = thr_id();printf("produto: Eu sou a thread %d, meu tid e %d\n", ord, tid);vet1[tid] *= vet2[tid];ev_signal(filhas);printf("produto: Eu sou a thread %d terminando...\n", ord);}
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 39
ev_config Modifica os parâmetros de um
semáforo do tipo EVENT. É possível alterar o número de threads
que sinalizarão o evento e o número de threads que esperarão pelo evento.
O semáforo deve estar inativo para que seus parâmetros possam ser modificados
Permite reutilização de semáforos
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 40
ev_config 1 1 1 int info=ev_config (EVENT sema, int nsignals, int nwaits);
info - se a chamada for bem sucedida retorna o valor 0, em caso de erro retorna um valor negativo.
sema - semáforo a ser modificado nsignals - novo número de threads que
devem sinalizar o evento nwaits - novo número de threads que
devem esperar pelo o evento
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 41
ev_set Causa a ativação forçada de um
evento. Todas as threads bloqueadas são
liberadas como se o evento tivesse acontecido.
O semáforo passa para o estado inativo
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 42
ev_set 1 int info = ev_set (EVENT sema);
info - se a chamada for bem sucedida retorna o valor 0, em caso de erro retorna um valor negativo.
sema - semáforo do tipo evento
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 43
ev_unset Causa a desativação forçada de um
evento. Todas as threads bloqueadas são
liberadas, sendo informadas através do código de retorno das rotinas ev_wait e ev_swait
O semáforo passa para o estado inativo
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 44
ev_unset 1 int info = ev_unset (EVENT sema);
info - se a chamada for bem sucedida retorna o valor 0, em caso de erro retorna um valor negativo.
sema - semáforo do tipo evento
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 45
Alocação de Memória As rotinas de alocação de memória da
biblioteca C podem causar problemas em programas com threads
O ambiente MULPLIX fornece suas próprias chamadas de maninpulação de memória.
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 46
me_alloc char *pnt = me_salloc (int size, int conc);
pnt - ponteiro para região alocada. Em caso de erro retorna NULL.
size - número de bytes a serem alocados
conc - se o valor for unitário a alocação será concentrada; se o valor for nulo a alocação será distribuída
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 47
me_salloc 1 Aloca uma região de memória no
segmento compartilhado O segmento compartilhado pode ser
acessado por todas as threads A região de memória deve ser
acessada por semáforos
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 48
me_sfree void = me_sfree (char *pnt); pnt - ponteiro para região alocada. Em
caso de erro retorna NULL. Libera uma região de memória alocada
no segmento de dados compartilhados
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 49
me_palloc char *pnt = me_palloc (int size);
pnt - ponteiro para região alocada. Em caso de erro retorna NULL.
size - número de bytes a serem alocados
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 50
me_palloc 1 Aloca uma região de memória no
segmento privado da thread Cada thread possui seu segmento de
dados privado A região de memória não precisa de
semáforos para ser acessada
@2003 Adriano Cruz NCE e IM - UFRJ Threads no Multiplus/Mulplix 51
me_pfree void = me_pfree (char *pnt); pnt - ponteiro para região alocada. Em
caso de erro retorna NULL. Libera uma região de memória alocada
no segmento de dados compartilhados