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

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

Sincronização com Posix Threads Sistemas Embutidos 2004.

Apresentações semelhantes


Apresentação em tema: "Sincronização com Posix Threads Sistemas Embutidos 2004."— Transcrição da apresentação:

1 Sincronização com Posix Threads Sistemas Embutidos 2004

2 Motivação Como compartilhar recursos? Processo 0Processo 1 Inicio lê (in) out = in imprime (out) Fim Inicio lê (in) out = in imprime (out) Fim

3 Revisão de Conceitos Condição de corrida Conjunto de eventos que levam a resultados não determinísticos Região Crítica Parte do código que implementa o acesso a um recurso compartilhado Exclusão mútua Mecanismo que impede o uso simultâneo de um recurso compartilhado

4 Um problema const n=50; var t: integer; procedure total; var count:integer; begin for count = 1 to n do t= t + 1 end; begin t=0; parbegin total; parend; write ( t ); end. A: Ra tRa Ra+1 t=0 Ra=1 B: t 49 Rb 49 t=49 Rb=49 A: t Ra t=1 B: Rb t Rb=1 A: t 50 t=50 B: Rb Rb+1 t 2 t=2

5 Semáforos Solução proposta por Dijkstra em 1965 Principio básico: um processo é suspenso enquanto não obtém permissão para executar uma RC e é acordado através de um sinal Para enviar um sinal via semáforo s o processo executa uma primitiva signal(s) e para receber um sinal via semáforo s o processo executa um primitiva wait(s)

6 Threads Modelo de Processo (únicoThread) Bloco de controle de processo Espaço de endereçamento do usuário Pilha Usuário Pilha Kernel Modelo MultiThread Bloco de controle de processo Espaço de endereçamento do usuário Pilha Usuário Pilha Kernel Bloco do controle Thread Pilha Usuário Pilha Kernel Bloco do controle Thread Pilha Usuário Pilha Kernel Bloco do controle Thread

7 Threads de Usuário Escalonamento e sincronização não passam pelo kernel Escalonamento é determinado pelo aplicativo Podem ser usadas em qualquer S.O. Chamadas ao sistema bloqueiam o processo Não pode fazer uso de mais de um processador

8 Threads de Kernel Threads do mesmo processo podem ser executados simultaneamente em processadores diferentes O bloqueio de um thread não bloqueia as demais threads de um processo Escalonamento e sincronização são muito custosos

9 LightWeightProcess Criação de threads é feita em modo usuário A maior parte do escalonamento e sincronização acontece em modo usuário Os threads em modo usuário são mapeadas num número possivelmente menor de threads do kernel

10 Comunicação entre Threads compartilhamento de recursos espaço de endereçamento de memória compartilhado técnicas de sincronização semelhante as utilizadas em processos

11 Threads no Linux Implementação no kernel através da função clone() Utilização da biblioteca Pthreads para garantir a portabilidade Em um programa em C, incluir o cabeçalho pthread.h e acrescentar –lpthread na linkedição.

12 Pthreads pthread_create(*t, *a, rotina, arg); t é um ponteiro para uma variável do tipo pthread_t que a é um ponteiro para os atributos. Os atributos são armazenados em uma variável do tipo pthread_attr_t. Um valor NULL indica o uso de valores default. Para detalhes veja pthread_attr_init(3) rotina é o nome (ponteiro) para a função que será executada. arg é um void * que é passado como argumento para rotina.

13 Pthreads A nova thread é disparada imediatamente e termina no retorno da função ou pela chamada da função pthread_exit(*ret) O argumento ret aponta uma variável que armazenará o valor de retorno. Já que pthread_exit nunca retorna, é de certa forma o equivalente à função exit.

14 Pthreads pthread_join(pthread_t id, void **return); pthread_detach(id ); id é identificação da thread return é o valor de retorno (pode ser NULL)

15 Pthreads - Sincronização Mutex int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex Variáveis de condição int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond);

16 Ex. Calculo de Pi #include volatile double pi = 0.0; pthread_mutex_t pi_lock; volatile double intervals; void *process(void *arg) { double width, localsum; int i; int iproc = (*((char *) arg) - 0); width = 1.0 / intervals; localsum = 0; for(i = iproc; i < intervals; i += 2) { register double x = (i + 0.5) * width; localsum += 4.0 / (1.0 + x * x); } localsum *= width; // Lock & Unlock before accessing PI pthread_mutex_lock(&pi_lock); pi += localsum; pthread_mutex_unlock(&pi_lock); return(NULL); } int main(int argc, char **argv) { pthread_t thread0, thread1; void * retval; intervals = atoi(argv[1]); //intervalos pthread_mutex_init(&pi_lock, NULL); if (pthread_create(&thread0, NULL, process, "0") || pthread_create(&thread1, NULL, process, "1")) { fprintf(stderr, "%s: cannot make thread\n", argv[0]); exit(1); } if (pthread_join(thread0, &retval) || pthread_join(thread1, &retval)) { fprintf(stderr, "%s: thread join failed\n", argv[0]); exit(1); } printf("Estimation of pi is %f\n", pi); exit(0); }

17 Sincronização de Threads Comunicação Serial

18 Características Um servidor pode receber/enviar mensagens através de uma porta serial RS485. A comunicação com um cliente só pode acontecer quando a linha estiver livre O acesso ao meio serial deve ser controlado por mutex

19 Problema RespServ GERENTE Contagem ConvL armazenamento Ocorrências de queda ou retorno de fase Poll Mensagens não transmitidas ao Servidor Fast Select Caso servidor não esteja disponível EnviaMsg Servidor

20 Programa principal int main(int argc, char **argv){ pthread_t tp; pthread_mutex_t lock; config_serial(); pthread_mutex_init(&lock,NULL); pthread_mutex_lock(&lock);//obtém lock pthread_mutex_init(&serial,NULL); if (pthread_create(&tp, NULL,(void *)Poll, NULL) ) { perror("Criacao da thread Poll"); exit(1); } while(1); }

21 Tratamento de relógio //Inicializa Timer void init_timer(){ struct sigaction timer; timer.sa_handler = handler_timer; timer.sa_flags = SA_RESTART; sigemptyset(&timer.sa_mask); sigaction(SIGALRM,&timer, NULL); } void handler_timer (){ int p; p =0; trata_relogio(p); } void trata_relogio(int p){ struct itimerval valor,ovalor; if (p == 1){ // liga timer valor.it_interval.tv_sec = 30; pthread_mutex_lock(&lock); }else{ // desliga timer valor.it_interval.tv_sec = 0; valor.it_value.tv_sec=0; pthread_mutex_unlock(&lock); } valor.it_interval.tv_usec = 0; valor.it_value = valor.it_interval; setitimer (ITIMER_REAL, &valor,0); }

22 Rotina Poll void Poll() { estado = INICIO_POLL; while (1) { switch (estado){ case INICIO_POLL: pthread_mutex_lock(&lock); // fica preso pthread_mutex_lock(&serial); // obtém meio serial case FIM_POLL: pthread_mutex_unlock(&serial); // libera meio serial trata_relogio(1); }

23 O que aconteceria... se durante um ciclo, a thread poll atualizasse uma tabela compartilhada na memória? se após o ciclo, esta tabela fosse atualizada no disco? Se durante o ciclo, uma outra thread retirasse um elemento da tabela? CUIDADO COM A ORDEM DOS SEMÀFOROS: SUJEITO A DEADLOCK

24 Exercício Altere o programa anterior para que os dados obtidos no ciclo de Poll sejam armazenados em um arquivo. Periodicamente este arquivo é lido por um outro thread e enviado via internet para um servidor remoto (simplesmente utilize uma função Envia( ) admitindo que está funcionando corretamente)


Carregar ppt "Sincronização com Posix Threads Sistemas Embutidos 2004."

Apresentações semelhantes


Anúncios Google