You are on page 1of 52

Engenharia da Computação

Sistemas de Tempo Real


Revisão de Programação Concorrente

Luis Claudio (lcoliveira.silva@gmail.com)


Introdução
Concorrência
Tipos de Concorrência
Por que estudar concorrência?
Processos e Threads
Processos e Threads
Tarefas
Thread X Processos
Estruturas e Funções Usadas
• Biblioteca pthread.h
– pthread_t (struct)
– pthread_create
– pthread_join
– pthread_kill
– pthread_exit
– outras (man pthreads – terminal

https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html

10
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);
}
for(i=0; i<2; i++) {
pthread_join(threads[i], NULL);
}
}

11
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);
}
for(i=0; i<2; i++) {
pthread_join(threads[i], NULL);
}
}
12
Exemplo de Thread (1/4)
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

/*Rotina que será executada*/


void * routine(void *arg);

int main (int argc, char *argv[])


{
pthread_t thread_id;
void * thread_res;
int rstatus;

/*tenta iniciar o thread, indicando a função 'routine' e passando


como argumento a string "Minha primeira Thread!"*/
rstatus = pthread_create (&thread_id, NULL, routine, (void*)("Minha
primeira Thread!"));
13
Exemplo de Thread (2/4)
/*verificar se ocorreu algum erro na chamada de pthread_create*/
if(rstatus != 0)
{
printf ("Erro ao criar o thread.\n");
exit(EXIT_FAILURE);
}

printf ("Thread criado com sucesso!\n");

/*aguarda finalização do thread identificado por thread_id. O retorno é


passado pelo ponteiro thread_res*/
rstatus = pthread_join (thread_id, &thread_res);

14
Exemplo de Thread (3/4)
/*verificar se ocorreu algum erro na chamada de pthread_join*/
if(rstatus != 0)
{
printf ("Erro ao aguardar finalização do thread.\n");
exit(EXIT_FAILURE);
}

/*exibe o valor de retorno da função 'routine'*/


printf ("Thread finalizado! Retorno = %s\n", (char *)thread_res);

return 0;
}

15
Exemplo de Thread (4/4)
void * routine(void *arg)
{
/*exibe o argumento recebido*/
printf("Argumento: %s\n", (char *)arg);

/*finaliza a função retornando o argumento que foi recebido*/


pthread_exit(arg);
}

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

17
Múltiplas Threads (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);
}
} 18
Múltiplas Threads (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]));
}
for(i=0; i<2; i++) {
pthread_join(threads[i], NULL);
}

19
20
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); 21


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]));
}
for(i=0; i<NUMTHREADS; i++) {
pthread_join(threads[i], NULL);
}
printf(“A soma dos numeros do vetor eh %d\n”, sum);
}
22
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 += i;
}
sum += localsum;
}

23
Somando Números (4/4)

Qual é o problema em potencial com o


programa anterior?

24
Alguns Conceitos
• Exclusão mútua (mutex)
– Técnica usada para evitar que dois processos ou threads tenham
acesso simultaneamente a um recurso compartilhado, denominado
seção crítica.
• Sessão crítica
– parte do programa que é executada por somente uma thread de cada
vez (em exclusão mútua)

25
Exercícios
1. Crie um programa multithread que calcule o valor da função f(x) = (sen(x))^3
+ sqrt(cos(x)), usando a série de Taylor com 20 termos. Cada Thread irá calcular
o valor de uma das duas funções.

2. Crie um programa multithread para calcular o produto de duas matrizes


inteiras quadradas de ordem 4. Devem ser criadas dezesseis threads, cada uma
para calcular um dos dezesseis elementos da matriz resultante.

3. Crie um programa multithread que realize uma busca de um número em um


vetor aleatório de 100 números inteiros. Devem ser criadas quatro threads e o
vetor deve ser populado com números aleatórios inteiros gerados pelo sistema.

26
Sincronização

27
Necessidade de sincronização
competitiva

28
Escalonamento

29
Problemas

30
Questões de Projeto

31
Problema Produtor-Consumidor

32
Controle do Buffer

33
Condições

34
Implementação

35
Problemas

36
Uma tentativa

37
Indeterminismo

38
Métodos de Sincronização

39
Semáforos

40
Tipos de Semáforos

41
Implementação

42
Exemplo

43
Implementação

44
Exemplo

45
Outro exemplo

46
Avaliação de Semáforos

47
Interface pthread para semáforo
• Header
– #include <semaphore.h>

• Tipo de dados

48
Interface pthread para semáforo
• Primitivas

49
Interface pthread para semáforo
• Sintaxe das primitivas

50
Resumindo...
...
#include <semaphore.h>
sem_t meusemaforo;

void main( … ) {

sem_init (&meusemaforo, 0 , 1);
… // Cria as threads, inicia, join, etc.
sem_destroy(&meusemaforo);
}

void funcao_thread( … ) {
...
sem_wait(&meusemaforo); // Inicio da regiao critica
// Operação crítica
sem_post(&meusemaforo); // Fim da regiao critica
...
}
51
Exercícios
Para o exercício abaixo, cronometre o tempo de operação. Use
semáforos para proteger a região crítica do programa.

• Elabore um programa que calcule uma aproximação para π, a


partir da série abaixo. Use 100 termos na série e 4 threads
para efetuar os cálculos.

52

You might also like