Programando com Threads em C

Slides:



Advertisements
Apresentações semelhantes
Sistemas de Interfaces com o Usuário e Glut/OpenGL
Advertisements

(Buffer Overflow…) Tópicos de Engenharia de Computação B
IC - UFF Sistemas Operacionais Threads. IC - UFF Processos e threads Vimos o conceito de processo englobando duas características básicas: propriedade.
C/C++ para Sistemas Operacionais Professor: André Luis Meneses Silva /msn: Página:
Introdução à Threads para Windows na linguagem C
Sistemas Operacionais
Funções em C.
Programação II Estruturas de Dados
1. Classes 2. Membros estáticos 1.1. Palavra chave this
Vamos abordar o exemplo
MPI – Comunicações Com. Colectiva esquecida Barrier não há troca de dados, apenas sincroniza os processos int MPI_Barrier( MPI_Comm, comm) T com = T lat.
14 de Dezembro de 2009 Teste Diehard aplicado ao gerador da biblioteca OpenSSL Segurança em Redes Móveis Elaborado por: Luís Ricardo Fonseca Instituto.
TADS – Tipos Abstratos de Dados
Funciona, porém está ilegível!
1 Java: Tratamento de Exceções Alcides Calsavara.
Sincronização com Posix Threads
PThreads MO801/MC972.
1 Estruturas de Controle Márcia J. N. Rodrigues Lucena Especialização em Técnicas e Ferramentas de Apoio à Decisão Departamento.
SSC SISTEMAS OPERACIONAIS I
SSC SISTEMAS OPERACIONAIS I
Walfredo Cirne Threads Walfredo Cirne
Linguagem de Programação C++
Threads.
SVCs para Controle de Processos no Unix
FORTRAN 90 Denise Yumi Takamura.
INTRODUÇÃO À COMPUTAÇÃO PARALELA
(Como implementar multiplicação e divisão uma vez só :-)
Buffer Overflow ou Stack Overrun ou Stack Smashing.
Funções de um computador
Capítulo VII – Tipos Enumerativos e Estruturas 7.1 – Tipos enumerativos 7.2 – A necessidade de estruturas 7.3 – Manipulação dos campos de uma estrutura.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013 Capítulo III Comandos de Controle.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013
1.3 – Interpretadores – Compiladores versus Interpretadores
CES-10 INTRODUÇÃO À COMPUTAÇÃO Aulas Práticas – 2013 Capítulo VII Variáveis Indexadas Numéricas.
CES-10 INTRODUÇÃO À COMPUTAÇÃO Capítulo XI Noções de Estruturas de Dados.
Capítulo IX – Ponteiros 9.1 – Introdução 9.2 – Relação entre ponteiros e variáveis indexadas 9.3 – Alocação dinâmica de memória 9.4 – Variáveis indexadas,
C/C++.
Recursividade Estrutura de Dados.
Curso de Programação em C++ Universidade Federal do Ceará Departamento de Engenharia Estrutural e Construção Civil Prof: Evandro Parente Junior Monitor:
LINGUAGENS DE PROGRAMAÇÃO
Programação Concorrente com Thread Java
INPE / CAP-334 Celso L. Mendes Aula 4-D(1) Reestruturação de Programas em Sistemas Vetoriais (II) Tópicos: Suporte à Paralelização Vetorização.
Slides: Prof. SIMÃO Revisão: Prof. João Fabro
Slides: Prof. João Fabro UTFPR - Curitiba
Professor: Hyggo Almeida
Threads, Gerenciamento de Threads Pool de Threads, Grupo de Threads Variáveis Locais à Threads.
Classes Revisando: –Forma de implementação de estruturas específicas –Atributos (grupos de dados) –Métodos (conjuntos de procedimentos)
PROGRAMAÇÃO ESTRUTURADA II
INPE / CAP-315 Airam J. Preto, Celso L. Mendes Aula 30 (1) Empacotamento de Dados em MPI Tópicos: Buffer de Mensagem Empacotamento/Desempacotamento.
INPE / CAP-315 Airam J. Preto, Celso L. Mendes Aula 27 (1) Programação com MPI Tópicos: Modelo de Programação Funções de Ambiente Funções Básicas.
Instruções condicionais
POO Ponto de Partida: PP Créditos: Prof. Marcelo Maia
Linguagem de Programação IV
UNIDADE 6 - complemento Funções recursivas
José Garcia Vivas Miranda
IC - UFF Sistemas Operacionais 4. Threads Texto base: capítulo 4 Operating Systems: Internals and Design Principles W. Stallings.
Tipos Especiais de Listas
Universidade Federal do Pará Instituto de Ciências Exatas e Naturais Faculdade de Computação SISTEMAS OPERACIONAIS Aula 9 Regiane Kawasaki
Estruturas de Dados Aula 11: TAD Pilha
Uso de parâmetros na linha de comando. Parâmetros da função main:
Programação de Sistemas Distribuídos e Concorrentes
Regras de escopo Escopo: trecho de codificação no qual o identificador possui significado Escopo de função: identificador válido dentro do trecho de uma.
Estruturas de Dados Aulas 3 e 4: Uso da memória e Vetores
Variáveis condicionais e Semáforos Aula de Concorrência.
Estrutura de Dados Revisão Professor Luiz José Hoffmann Filho
Fundamentos de Programação 1 Slides 18 Prof. SIMÃO Jean Marcelo SIMÃO Linguagem C “Arquivos Seqüências ou de Texto ”.
Fundamentos de Programação 1 Slides 21 Prof.ª Fabiany e Prof. SIMÃO Linguagem C “Lista Encadeada”.
Fundamentos de Programação 1 Slides 22 Prof.ª Fabiany e Prof. SIMÃO Linguagem C “Lista Duplamente Encadeada - Projeto com vários Arquivos”.
Fundamentos de Programação 1 Slides 18 Prof. SIMÃO Jean Marcelo SIMÃO Linguagem C “Arquivos Seqüências ou de Texto ”. 1.
Pthreads – POSIX Threads
Transcrição da apresentação:

Programando com Threads em C AEDS III Bruno Diniz de Paula (diniz@dcc.ufmg.br)

O que são Threads? Linhas de execução concorrentes Memória (pilha) independente Podem compartilhar áreas de memória Processo 1 Início Threads Fim

Problemas Sincronização entre elas Localização de erros Condições de corrida (race conditions) Deadlock’s Localização de erros Difícil garantia de correção dos programas (modelos analíticos e verificação formal) Imprevisibilidade

Estruturas e Funções Usadas Biblioteca pthread.h pthread_t (struct) pthread_create pthread_join pthread_kill pthread_exit outras (man pthreads - turmalina)

Criação de Threads pthread_t threads[2]; void *thread_func(void *arg) { ... } int main(int argc, char **argv) { int i; for(i=0; i<2; i++) { pthread_create(&(threads[i]), NULL, thread_func, NULL); pthread_join(threads[i], NULL);

Passando Parâmetros pthread_t threads[2]; void *thread_func(void *arg) { int *n = (int *)arg; ... } int main(int argc, char **argv) { int i, a = 10; for(i=0; i<2; i++) { pthread_create(&(threads[i]), NULL, thread_func, &a); pthread_join(threads[i], NULL);

Um Programa Completo (1/2) #include <stdlib.h> #include <stdio.h> #include <pthread.h> typedef struct { int idx, length; }thread_arg, *ptr_thread_arg; pthread_t threads[2]; void *thread_func(void *arg) { ptr_thread_arg targ = (ptr_thread_arg)arg; int i; for(i=targ->idx; i<(targ->idx + targ->length); i++) { printf(“Thread %d – value %d\n”, pthread_self(), i); }

Um Programa Completo (2/2) int main(int argc, char **argv) { thread_arg arguments[2]; int i; for(i=0; i<2; i++) { arguments[i].idx = i * 10; arguments[i].length = 10; pthread_create(&(threads[i]), NULL, thread_func, &(arguments[i])); } pthread_join(threads[i], NULL);

Compilando Biblioteca de pthreds é dinâmica Linha de comando gcc ... -lpthread

Somando Números (1/4) #include <stdlib.h> #include <stdio.h> #include <pthread.h> #define NUMTHREADS 2 #define VETSIZE 5000 typedef struct { int fromidx, length; }thread_arg, *ptr_thread_arg; pthread_t threads[NUMTHREADS]; thread_arg arguments[NUMTHREADS]; int nums[VETSIZE]; int sum; void *thread_func(void *arg);

Somando Números (2/4) int main(int argc, char **argv) { int i, length, remainder; sum = 0; length = VETSIZE / NUMTHREADS; remainder = VETSIZE % NUMTHREADS; for(i=0; i<NUMTHREADS; i++) { arguments[i].fromidx = i * length; arguments[i].length = length; if(i == (NUMTHREADS - 1)) arguments[i].length += remainder; pthread_create(&(threads[i]), NULL, thread_func, &(arguments[i])); } pthread_join(threads[i], NULL); printf(“A soma dos numeros do vetor eh %d\n”, sum);

Somando Números (3/4) void *thread_func(void *arg) { ptr_thread_arg argument = (ptr_thread_arg)arg; int i, localsum = 0, endidx; endidx = argument->fromidx + argument->length; for(i=argument->fromidx; i<endidx; i++) { localsum += nums[i]; } sum += localsum;

Qual é o problema com o programa anterior? Somando Números (4/4) Qual é o problema com o programa anterior?

Solução Sincronização!!! Cenas do próximo capítulo! (5a. Feira)

Alguns Conceitos Exclusão mútua Sessão crítica uma thread está executando sozinha um determinado código, enquanto as outras esperam para poder executar Sessão crítica parte do programa que é executada por somente uma thread de cada vez (em exclusão mútua)

Primitivas de Sincronização Semáforos Monitores Troca de mensagens

Estruturas e Funções Usadas pthread_mutex_t (struct) – sem. binário pthread_mutex_lock pthread_mutex_unlock sem_t (struct) – sem. não binário sem_wait sem_post

Produtor / Consumidor (1/4) Buffer Compartilhado Produtor

Produtor / Consumidor (2/4) #include <stdlib.h> #include <stdio.h> #include <pthread.h> #define NUMCONS 2 #define NUMPROD 2 #define BUFFERSIZE 1000 pthread_t cons[NUMCONS]; Pthread_t prod[NUMPROD]; int buffer[BUFFERSIZE]; Int currentidx; void *consumidor(void *arg); Void *produtor(void *arg);

Produtor / Consumidor (3/4) int main(int argc, char **argv) { int i; srand48(time()); currentidx = 0; for(i=0; i<NUMCONS; i++) { pthread_create(&(cons[i]), NULL, consumidor, NULL); } for(i=0; i<NUMPROD; i++) { pthread_create(&(prod[i]), NULL, produtor, NULL); pthread_join(cons[i], NULL); pthread_join(prod[i], NULL);

Produtor / Consumidor (4/4) void *produtor(void *arg) { int n; while(1) { n = (int)(drand48() * 1000.0); buffer[currentidx++] = n; printf(“Produzindo numero %d\n”, n); sleep((int)(drand48() * 4.0)); } void *consumidor(void *arg) { n = buffer[--currentidx]; printf(“Consumindo numero %d\n”, n);

Qual é o problema com o programa anterior? E de novo... Qual é o problema com o programa anterior?

1a. Tentativa de Solução (1/4) #include <stdlib.h> #include <stdio.h> #include <pthread.h> #define NUMCONS 2 #define NUMPROD 2 #define BUFFERSIZE 1000 pthread_t cons[NUMCONS]; pthread_t prod[NUMPROD]; pthread_mutex_t buffer_mutex; int buffer[BUFFERSIZE]; int currentidx; void *consumidor(void *arg); Void *produtor(void *arg);

1a. Tentativa de Solução (2/4) int main(int argc, char **argv) { int i; srand48(time()); currentidx = 0; pthread_mutex_init(&buffer_mutex, NULL); for(i=0; i<NUMCONS; i++) { pthread_create(&(cons[i]), NULL, consumidor, NULL); } for(i=0; i<NUMPROD; i++) { pthread_create(&(prod[i]), NULL, produtor, NULL); pthread_join(cons[i], NULL); pthread_join(prod[i], NULL);

1a. Tentativa de Solução (3/4) void *produtor(void *arg) { int n; while(1) { n = (int)(drand48() * 1000.0); pthread_mutex_lock(&buffer_mutex); buffer[currentidx++] = n; pthread_mutex_unlock(&buffer_mutex); printf(“Produzindo numero %d\n”, n); sleep((int)(drand48() * 4.0)); }

1a. Tentativa de Solução (4/4) void *consumidor(void *arg) { int n; while(1) { pthread_mutex_lock(&buffer_mutex); n = buffer[--currentidx]; pthread_mutex_unlock(&buffer_mutex); printf(“Consumindo numero %d\n”, n); sleep((int)(drand48() * 4.0)); }

Quem controla a ocupação do buffer? Agora sim... Ficou correto? Não!!!! Por quê? Quem controla a ocupação do buffer?

2a. Tentativa de Solução (1/4) #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <sem.h> #define NUMCONS 2 #define NUMPROD 2 #define BUFFERSIZE 1000 pthread_t cons[NUMCONS]; pthread_t prod[NUMPROD]; pthread_mutex_t buffer_mutex; int buffer[BUFFERSIZE]; int currentidx; sem_t buffer_full, buffer_empty; void *consumidor(void *arg); Void *produtor(void *arg);

2a. Tentativa de Solução (2/4) int main(int argc, char **argv) { int i; srand48(time()); currentidx = 0; pthread_mutex_init(&buffer_mutex, NULL); sem_init(&buffer_full, 0, 0); sem_init(&buffer_empty, 0, 0); for(i=0; i<NUMCONS; i++) { pthread_create(&(cons[i]), NULL, consumidor, NULL); } for(i=0; i<NUMPROD; i++) { pthread_create(&(prod[i]), NULL, produtor, NULL); ...

2a. Tentativa de Solução (3/4) void *produtor(void *arg) { int n; while(1) { n = (int)(drand48() * 1000.0); pthread_mutex_lock(&buffer_mutex); if(currentidx == BUFFERSIZE) { pthread_mutex_unlock(&buffer_mutex); sem_wait(&buffer_full); }else{ buffer[currentidx++] = n; if(currentidx == 1) sem_post(&buffer_empty); printf(“Produzindo numero %d\n”, n); } sleep((int)(drand48() * 4.0));

2a. Tentativa de Solução (4/4) void *consumidor(void *arg) { int n; while(1) { pthread_mutex_lock(&buffer_mutex); if(currentidx > 0) { n = buffer[--currentidx]; if(currentidx == (BUFFERSIZE – 1)) sem_post(&buffer_full); pthread_mutex_unlock(&buffer_mutex); printf(“Consumindo numero %d\n”, n); }else{ sem_wait(&buffer_empty); } sleep((int)(drand48() * 4.0));

Barreira (1/3) Arquivo barrier.h typedef struct { pthread_mutex_t mutex; sem_t waitsem; int nthreads, current; }barrier_t, *ptr_barrier_t; void barrier_init(ptr_barrier_t, int); void barrier(ptr_barrier_t);

Barreira (2/3) Arquivo barrier.c void barrier_init(ptr_barrier_t pbarrier, int nt) { pbarrier->nthreads = nt; pbarrier->current = 0; pthread_mutex_init(&(pbarrier->mutex), NULL); sem_init(&(pbarrier->waitsem), 0, 0); }

Barreira (3/3) Arquivo barrier.c void barrier(ptr_barrier_t pbarrier) { int i; pthread_mutex_lock(&(pbarrier->mutex)); pbarrier->current++; if(pbarrier->current < pbarrier->nthreads) { pthread_mutex_unlock(&(pbarrier->mutex)); sem_wait(&(pbarrier->waitsem)); }else{ for(i=0; i<(pbarrier->nthreads - 1); i++) sem_post(&(pbarrier->waitsem)); pbarrier->current = 0; }

Agora... ... é só sair programando usando threads loucamente e tirar total no trabalho de AEDS!  Obrigado!