A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Linguagem de Programação IV

Apresentações semelhantes


Apresentação em tema: "Linguagem de Programação IV"— Transcrição da apresentação:

1 Linguagem de Programação IV
Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação

2 Threads

3 O que são Threads? Enquanto um processo é um meio de agrupar recursos, threads são as entidades escalonadas para a execução sobre a CPU. Acrescentam ao modelo de processo a possibilidade que múltiplas execuções ocorram no mesmo ambiente de um processo e com um grande grau de independência uma da outra.

4 Recursos X escalonamento/execução
Processos e Threads Recursos X escalonamento/execução Características essenciais de um processo são inseparáveis e tratadas em conjunto pelo S.O. Características independentes Podem ser tratadas independentemente pelo S.O. Unidade de escalonamento é a thread (lightweight process) Unidade de posse de recursos é o processo/tarefa

5 Threads Threads também são chamados de lightweight process ou processos leves. O termo Multithread também é usado para descrever a situação em que se permite a existência de múltiplos threads no mesmo processo.

6 Multithreading Capacidade do Sistema Operacional suportar múltiplas threads de execução dentro de um único processo

7 Single-Thread x Multithread
um processo uma thread um processo várias threads vários processos uma thread por processo vários processos várias threads por processo

8 Funcionamento de uma Thread
Threads distintos em um processo não são tão independentes quanto processos distintos, todos os threads tem exatamente o mesmo espaço de endereçamento. Ou seja, isso significa que eles também compartilham as mesmas variáveis globais.

9 Funcionamento de uma Thread
Cada thread pode ter acesso a qualquer endereço de memória dentro do espaço de endereçamento do processo. Um thread pode ler, escrever ou até mesmo apagar os dados de outra thread. É impossível um processos distintos acessar aos dados de outro processo.

10 Modelo de Processo (single thread)
Espaço de endereçamento para armazenamento da imagem do processo (espaço de usuário e de sistema) Informações de recursos alocados são mantidos no descritor de processos Contexto de execução (pilha, programa, dados, ...) processo pilha código dados Espaço de usuário SP PC dados pilha Espaço de sistema

11 Vários processos Um fluxo de controle por processo (thread)
Troca do processo implica em atualizar estruturas de dados internas do S.O. Contexto, espaço de endereçamento, . . . Espaço de usuário processo processo pilha código dados pilha código dados SP PC SP PC Espaço de sistema dados pilha dados pilha

12 Vários fluxos em um único processo
Um fluxo de instrução é implementado através do PC e SP Estruturas comuns compartilhadas Código Dados Descritor de processos conceito de thread processo SP1 pilha PC1 código dados Espaço de usuário SP2 PC2 SP3 PC3 Espaço de sistema dados pilha

13 Multiprogramação Pesada
Custo do gerenciamento de processos criação do processo troca de contextos esquemas de proteção, memória virtual, etc... Custos são fator limitante na interação de processos unidade de manipulação é o processo Mecanismos de IPC necessitam a manipulação de estruturas complexas que representam o processo e suas propriedades (através de chamadas de sistema) Solução “Aliviar” os custos, reduzir o overhead envolvido

14 Multiprogramação Leve
Fornecido pela abstração de um fluxo de execução (thread) Unidade de interação passa a ser função Contexto de uma thread Registradores(pilha, apontador de programa, registradores de uso geral) Comunicação por memória compartilhada

15 Por que utilizar threads?
Permitir a exploração do paralelismo real oferecido por máquinas multiprocessadas Aumentar o número de atividades executadas por unidade de tempo (throughput) Esconder latência do tempo de resposta possibilidade de associar threads a dispositivos de I/O Sobrepor operações de cálculo com operações de I/O

16 Estados de uma Thread Estados fundamentais: Executando Pronta
Bloqueada

17 Vantagens do Multithreading
Tempo de criação/destruição de threads é inferior que tempo de criação/destruição de processos Chaveamento de contexto entre threads é mais rápido que tempo de chaveamento entre processos Como threads compartilham o descritor do processo, elas dividem o mesmo espaço de endereçamento o que permite a comunicação por memória compartilhada sem interação com o núcleo (kernel) do S.O.

18 Segurança de Threads Não há proteção entre as threads. Porque?
É impossível Não é necessário (Todas as threads presumidamente são criadas pelo mesmo usuário) Threads foram criadas para cooperar e não competir

19 Em que nível implementar?
Nível do usuário Gerenciamento dos Threads é feito pela aplicação. Escalonamento é feito pela aplicação

20 Threads x Processos Processo Thread _ real user sys _ real user sys
INTEL 2.2 GHz Xeon 2 CPU/node 2 GB Memory RedHat Linux 7.3

21 Exemplo - RPC

22 Exemplo - RPC

23 Exemplo Thread A (proc. 1) Thread B (proc. 1) Thread C (proc. 2) I/O
preempt Thread A (proc. 1) Thread B (proc. 1) Thread C (proc. 2) preempt criação processo novo bloqueado pronto em execução t

24 Implementação de Threads
Threads são implementadas através de estrutura de dados similares ao descritor de processo Descritor de threads Menos complexa (leve) Podem ser implementadas em dois níveis diferentes espaço de usuário (user level threads) espaço de sistema (kernel level threads)

25

26 Single Threaded x Multithreaded
block thread block thread block process control block user stack user stack user stack user stack process control block kernel stack user address space kernel stack kernel stack kernel stack user address space

27 Modelo 1:1 Threads a nível de usuário
user level threads ou process scope Todas as tarefas de gerenciamento de threads é feito a nível da aplicação threads são implementadas por uma biblioteca que é ligada ao programa Interface de programação (API) para funções relacionadas com threads Ex: criação, sincronismo, término, etc ... O sistema operacional não “enxerga” a presença das theads A troca de contexto entre threads é feita em modo usuário pelo escalonador embutido na biblioteca não necessita privilégios especiais escalonamento depende da implementação

28 Implementação do modelo 1:1
PC1 SP1 processo Espaço de usuário PC2 SP2 SP pilha código dados escalonador biblioteca PC PCn SP3 CPU virtual biblioteca Espaço de sistema dados pilha escalonador sistema operacional CPU

29 Modelo 1:1 Vantagens Desvantagens
Sistema operacional divide o tempo do processador entre os processos “ pesados” e, a biblioteca de threads divide o tempo do processo entre as threads Leve: sem interação/intervenção do S.O. Desvantagens Uma thread que realiza uma chamada de sistema bloqueante bloqueia todo o processo e suas threads Não explora o paralelismo das máquinas multiprocessadas

30 Modelo N:1 Threads a nível de sistema
kernel level threads ou system scope Resolve desvantagens do modelo 1:1 O sistema operacional “enxerga” as threads S.O. mantém informações sobre processos e sobre threads troca de contexto necessita a intervenção do S.O. O conceito de threads é considerado na implementação do S.O.

31 Implementação do modelo N:1
PC1 SP1 processo Espaço de usuário PC2 SP2 SP pilha código dados PC CPU virtual CPU virtual CPU virtual PCn SP3 Espaço de sistema dados pilha escalonador sistema operacional CPU

32 Modelo N:1 Vantagens Desvantagens
Explora paralelismo da máquinas multiprocessadas (SMP) Facilita o recobrimento de operações de operações de I/O por cálculos Desvantagens Implementação “mais pesada” que o modelo 1:1

33 Modelo 1:N Permite que uma thread migre de um processo para outro.
Isto permite a movimentação da thread entre sistemas distintos

34 Modelo M:N Abordagem que combina os modelos N:1 e 1:N

35 PTHREADS IEEE POSIX 1003.1c standard (1995).
Implementações que aderem a este padrão são denominados como POSIX threads ou Pthreads Definido como um conjunto de tipos e chamadas de procedimentos da linguagem C, implementada com um arquivo “header/include” pthread.h e uma biblioteca de threads

36 Projeto de Programas com Threads
Para que um programa tenha um melhor desempenho com threads ele precisa ser organizado em tarefas distintas e independentes que podem ser executadas concorrentemente Por exemplo, se tivermos dois ou mais procedimentos que podem ser trocados de ordem de execução, intercalados ou sobrepostos em tempo real, então eles são candidatos a serem implementados em threads distintas

37 Projeto de Programas com Threads
Procedimento 1 Procedimento 2 Proc Final Procedimento 2 Procedimento 1 Proc Final P2 P1 P2 P1 P2 P1 P2 P1 Proc Final Procedimento 2 Proc Final Procedimento 1

38 Tarefas candidatas a serem implementadas em threads distintas
Tarefas que Têm um potencial de ficarem bloqueadas por um longo tempo Usam muitos ciclos de CPU Que devem responder a eventos assíncronos Que tenham uma importância menor ou maior do que outras tarefas Que são aptas de serem executadas em paralelo com outras tarefas

39 API Pthread Podem ser grupadas em três classes
Gerenciamento de threads Criar, destruir, atachar, etc... threads Mutexes Criar, destruir, trancar e destrancar mutexes Variáveis de condição Funções de comunicação entre threads que têm mutexes em comum. Funções para criar, destruir, wait e signal, set e query de variáveis de condição

40 Convenção de nomes Routine Prefix Functional Group
pthread_ Threads and miscellaneous subroutines pthread_attr_ Thread attributes objects pthread_mutex_ Mutexes pthread_mutexattr_ Mutex attributes objects. pthread_cond_ Condition variables pthread_condattr_ Condition attributes objects pthread_key_ Thread-specific data keys

41 Gerenciamento de threads
Criar threads pthread_create (thread,attr,start_routine,arg) pthread_exit (status) pthread_attr_init (attr) pthread_attr_destroy (attr)

42 Criando e terminando threads
Criar threads pthread_create (thread,attr,start_routine,arg) Finalizar threads pthread_exit (status) Definir atributos pthread_attr_init (attr) Remover atributos pthread_attr_destroy (attr)

43 Criando threads main() cria uma thread. As outras devem ser criadas pelo programador pthread_create: cria uma nova thread (pode ser chamada varias vezes) Argumentos da função: thread: identificador para nova thread que será retornado pela rotina attr: conjunto de atributos para definição das threads que serão criadas. NULL para valores default start_routine: a função que será executada assim que a thread for criada arg: Um argumento que será passado para a função. Ele deve ser passado por referencia com um ponteiro do tipo void (casting). NULL pode ser utilizado para não passar argumentos O numero maximo de threads que podem ser criadas depende da implementação Uma vez criadas as threads são “irmãs”. Não existe o conceito de hierarquia ou dependencia entre threads.

44 Terminando threads Threads podem ser terminadas de varias formas.
A thread volta para a rotina que a criou (função main para thread inicial) A thread faz uma chamada para a função pthread_exit() A thread é cancelada por outra thread através da função pthread_cancel() O processo inteiro é terminado

45 % gcc –o thread thread.c –lpthread % ./thread
#include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *PrintHello(void *threadid){ printf("\n%d: Hello World!\n", threadid); pthread_exit(NULL); } int main(int argc, char *argv[]){ pthread_t threads[NUM_THREADS]; int rc, t; for(t=0;t<NUM_THREADS;t++){ printf("Creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); Exemplo de criação e Destruição de Thread % gcc –o thread thread.c –lpthread % ./thread

46 Passagem de parâmetros
A melhor maneira de passar parametros é atraves do uso de uma estrutura Cada thread recebe uma instância da estrutura

47 Exemplo de criação com passagem de parametros
#include <pthread.h> #include <stdio.h> struct thread_data{ int thread_id; int sum; char *message; }; struct thread_data thread_data_array[NUM_THREADS]; void *PrintHello(void *threadarg){ struct thread_data *my_data; ... my_data = (struct thread_data *) threadarg; taskid = my_data->thread_id; sum = my_data->sum; hello_msg = my_data->message; ... } int main (int argc, char *argv[]){ thread_data_array[t].thread_id = t; thread_data_array[t].sum = sum; thread_data_array[t].message = messages[t]; rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &thread_data_array[t]); } Exemplo de criação com passagem de parametros para as threads usando estrutura

48 União e separação de threads (join and detach)
pthread_join (threadid,status) Separação pthread_detach (threadid) Definição de atributos pthread_attr_setdetachstate (attr,detachstate) pthread_attr_getdetachstate (attr,detachstate)

49 União (join) Mecanismo de sincronização de threads
Pode ser usado mutexes e condições pthread_join() bloqueia a função chamadora até que a thread threadid termine O programador pode obter o status do termino de uma thread se ele for especificado em pthread_exit(). Uma união pode esperar somente um pthread_join(). É um erro lógico esperar por multiplos joins na mesma thread pthread_detach() pode ser usado para explicitamente detach uma thread mesmo que ela tenha sido criada como joinable.

50 Joinable or Not? Quando uma thread é criada um de seus atributos é a definição se uma thread é joinable ou não. Somente threads criadas como joinable podem ser unidas (joined). Threads criadas como detachabled nunca podem ser unidas O padrão POSIX diz que threads tem de ser criadas como joinable Para explicitar uma thread como joinable deve ser definido seu atributo na criação Criar atributo do tipo pthread_attr_t  pthread_attr_t attr; Inicializar os atributos  pthread_attr_init() Definir o status de detach  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); Quando terminar, liberar recursos usados pelos atributos  pthread_attr_destroy()

51 Joinable or joining

52 if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } }
/* Free attribute and wait for the other threads */ pthread_attr_destroy(&attr); for(t=0; t<NUM_THREADS; t++) { rc = pthread_join(thread[t], &status); if (rc) { printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status); } printf("Main: program completed. Exiting.\n"); pthread_exit(NULL); } #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #define NUM_THREADS 4 void *BusyWork(void *t){ int i; long tid; double result=0.0; tid = (long)t; printf("Thread %ld starting...\n",tid); for (i=0; i< ; i++) result = result + sin(i) * tan(i); printf("Thread %ld done. Result = %e\n",tid, result); pthread_exit((void*) t); } int main (int argc, char *argv[]){ pthread_t thread[NUM_THREADS]; pthread_attr_t attr; int rc; long t; void *status; /* Initialize and set thread detached attribute */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for(t=0; t<NUM_THREADS; t++) { printf("Main: creating thread %ld\n", t); rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); Saída: Main: creating thread 0 Main: creating thread 1 Thread 0 starting… Main: creating thread 2 Thread 1 starting… Main: creating thread 3 Thread 2 starting… Thread 3 starting… Thread 1 done. Result = e+06 Thread 0 done. Result = e+06 …. Main: program completed. Exiting.

53 Threads e Mutexes Mutexes são usados para controlar acesso a variaveis compartilhadas Variáveis mutexes precisam ser declaradas pthread_mutex_t Criar e destruir mutexes pthread_mutex_init (mutex,attr) pthread_mutex_destroy (mutex) Definir e destribuir atributos de mutexes pthread_mutexattr_init (attr) pthread_mutexattr_destroy (attr) Lock e unlock pthread_mutex_lock (pthread_mutex_t *mut); pthread_mutex_unlock (pthread_mutex_t *mut);

54 #include <stdio. h> #include <stdlib
#include <stdio.h> #include <stdlib.h> #include <pthread.h> void *functionC(); pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; int counter = 0; main(){ int rc1, rc2; pthread_t thread1, thread2; /* Create independent threads each of which will execute functionC */ if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) ){ printf("Thread creation failed: %d\n", rc1); } if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) ){ printf("Thread creation failed: %d\n", rc2); } /* Wait till threads are complete before main continues. Unless we */ /* wait we run the risk of executing an exit which will terminate */ /* the process and all threads before the threads have completed. */ pthread_join( thread1, NULL); pthread_join( thread2, NULL); exit(0); } void *functionC() { pthread_mutex_lock( &mutex1 ); counter++; printf("Counter value: %d\n",counter); pthread_mutex_unlock( &mutex1 ); }


Carregar ppt "Linguagem de Programação IV"

Apresentações semelhantes


Anúncios Google