Programação com memória partilhada (exemplos)

Documentos relacionados
Só podem ser executados por uma Thread que detenha o lock do objecto

Programação em sistemas de memória distribuída

LabSO Gerência de Processos. Retrospectiva da aula passada... Na aula passada... Na aula passada...

Programação com memória partilhada

Sistemas Operacionais: Sincronização entre processos

Programação concorrente em Java

Sistemas Operacionais

[Magee 1999] Concurrency State Models and Java Programs, Jeff Magee, Jeff Kramer, John Wiley 1999.

Filas. Nesta aula veremos o ADT fila Em um computador existem muitas filas esperando pela impressora, acesso ao disco ou, num sistema timesharing,

Sistemas Operacionais. Prof. André Y. Kusumoto

[Magee 1999] Concurrency State Models and Java Programs, Jeff Magee, Jeff Kramer, John Wiley 1999.

Prof. Silvana Rossetto 9 de julho de DCC/IM/UFRJ

Exercício de Estrutura de dados. Java Fila

Algoritmos e estrutura de dados

Threads. Linguagem Java. Adenilso da Silva Simão 17/05/05

Sistemas Operacionais. Prof. André Y. Kusumoto

Universidade da Beira Interior. Sistemas Distribuídos. Folha 4-1. Threads Daemon Threads

Programação I Aula 11 Mais sobre ciclos e iteração

Sistemas Operacionais

Introdução à Programação / Programação I

Threads e Sincronização no Linux

ACH5531 Introdução à Computação Estruturas de repetição

Processamento da Informação Teoria. Laços

Sistemas Distribuídos Aula 7

Sincronização. Cooperação entre Processos

[Magee 1999] Concurrency State Models and Java Programs, Jeff Magee, Jeff Kramer, John Wiley 1999.

Cooperação entre Processos

Programação Orientada a Objetos. Concorrência

Sincronização. Objectivos da aula de hoje

Processamento da Informação Teoria. Laços aninhados

Problema do Produtor -Consumidor. Solução por semáforos

Programação Concorrente e Paralela August 28, 2013

Threads. Leonardo Gresta Paulino Murta

Aula 6: Comunicação entre processos. Instituto Federal da Bahia INF009 - Sistemas Operacionais Profª Flávia Maristela

Programação Concorrente e Paralela

Computação 1 - Python Aula 9 - Teórica: Interferindo no fluxo de repetição: Break e Continue Laços Aninhados

Sistemas Operacionais

Sistemas Operativos 2014/15

Python: Exceções, Iteradores e Geradores. Claudio Esperança

Monitores. Paulo Sérgio Almeida. Grupo de Sistemas Distribuídos Departamento de Informática Universidade do Minho

Problemas Típicos de Sincronização

Sistemas Operacionais. Sincronização: Semáforos Problema dos Leitores/Escritores

UNIP - Ciência da Computação e Sistemas de Informação. Estrutura de Dados. AULA 5 Pilhas

Threads em Java. Java Threads. Java Componentes: JVM JVM:

Sincronização. Cooperação entre Processos

Computação Paralela e Distribuída. Heucles Jr

Computação 1 - Python Aula 7 - Teórica: Estrutura de Repetição com teste de parada: while 1/ 23

Computação 2. Aula 6 Teórica professor: Leonardo Carvalho

aula05 September 6, 2018

Prova de Recuperação PMR3201 1o. semestre 2017 Prof. Thiago Martins

Nesta aula... Parâmetros opcionais Atribuição abreviada Instruções break e continue Interrupção da execução. 1 Estudo desta disciplina.

Conceito de Processo. Estados de Processos. Diagrama de Estados de Processos

Sistemas Operacionais. Deadlock

Prova Substitutiva PMR3201 1o. semestre 2018 Prof. Thiago Martins

Impasses. Pedro Cruz. EEL770 Sistemas Operacionais

LEIC/LERC 2008/09 Primeiro Teste de Sistemas Operativos

Retrospectiva da aula passada... Escalonamento. Na aula passada... Comunicação entre processos (-- O jantar dos filósofos --)

Computação 2. Aula 7 Teórica professor: Leonardo Carvalho

Métodos Sincronizados

Sistemas Distribuídos Aula 5

Programação concorrente (processos e threads)

Tratamento de Exceções, Multithreads e arquivos (em Java) Programação Orientada a Objetos

Capítulo 6: Sincronização de Processos. Operating System Concepts 8th Edition

Sincronização de Processos (2)

Programação Concorrente Locks

Aula 7. Problemas Clássicos de Sincronização. 1.1 O Jantar dos Filósofos. 1.2 Leitores e Escritores. 1.3 O Barbeiro Dorminhoco

Prova Final de Linguagens de Programação - DCC024B -

O PROBLEMA DOS LEITORES E ESCRITORES LABORATORIO 1

Lista de Linguagens de Programação 16

Sincronização. Cooperação entre Processos

Informática UFRGS. Threads. Programação com Objetos Distribuídos (C. Geyer) C# Threads V5 1

Sistemas Operacionais

Sincronização de Threads

LabSO Gerência de Processos. Processos. Porque eu preciso entender este assunto?

Teste de Sistemas de Operação 30 de Maio de 2009

M etodos Matem aticos e de Computa c ao II VIII XI/2016

Programação Concorrente Benito Fernandes Fernando Castor João Paulo Oliveira Weslley Torres

Implementando uma demonstração

MAC2166 Introdução à Computação

Errata* do livro Programação em Python Fundamentos e Resolução de Problemas

Fundamentos da Programação

Árvores. Thiago Martins, Fabio Gagliardi Cozman. PMR2300 / PMR3201 Escola Politécnica da Universidade de São Paulo

Introdução à Programação Aula 11 Mais sobre ciclos e iteração

MCG126 Programação de Computadores II

Prova Final de Linguagens de Programação - DCC024 - Sistemas de Informação

Listas, conjuntos e dicionários

Escalonamento. Pedro Cruz. EEL770 Sistemas Operacionais

Laços de repetição for, while, do-while

Universidade da Beira Interior. Sistemas Distribuídos

Estrutura de Dados. Diego Silveira Costa Nascimento

Redes de Computadores. INF201 - Fundamentos de Sistemas Operacionais - 2º Período

Algoritmos e estrutura de dados

Processamento da Informação Teoria. Recursividade

A resposta apresentada em aula, no quadro, (em Chapin e/ou Português Estruturado) está correta?

MAC2166 Introdução à Computação

Computação 1 - Python Aula 8 - Teórica: Estrutura de Repetição : for 1/ 10

INTRODUÇÃO À COMPUTAÇÃO - RESUMO E EXERCÍCIOS* P2

Concorrência. Sistemas Distribuídos e Tolerância a Falhas. Lia Ribeiro 1

Prova Final de Linguagens de Programação - DCC024B -

Nome: Número: Primeira Parte (7 valores) Segunda Parte (3 valores)

Transcrição:

Programação com memória partilhada (exemplos) 1

A classe queue.queue Classe que implementa uma fila (FIFO) sincronizada. - Usa locks para bloquear threads que competem pelo acesso aos elementos da fila. Constructor: Queue(maxsize=0) - maxsize estabelece um limite máximo para o número de itens na fila - Quando o limite é atingido, as operações de inserção serão bloqueadas, até ser consumido algum item. - Se maxsize <= 0 o tamanho da fila é infinito. 2

Outras classes do módulo queue: class queue.lifoqueue(maxsize=0) class queue.priorityqueue(maxsize=0) exception queue.full exception queue.empty 3

Outros métodos das classes Queue: Queue.qsize() - Devolve o tamanho da fila. - qsize() > 0 não garante que a operação seguinte de get não bloqueie - qsize() < maxsize não garante que a operação seguinte de put não bloqueie. Queue.empty() - Devolve True se fila vazia, False caso contrário - Se empty() devolve True isso não garante que a operação seguinte de put não bloqueie. - Se empty() devolve False garante que a operação seguinte de get não bloqueie 4

Outros métodos das classes Queue: Queue.full() - Devolve True se a vila está cheia, False caso contrário. - Queue.put( item, block=true, timeout=none) - Insere um item na fila. Se block é true e timeout é None (valores de omissão), a operação bloqueia até que exista espaço para inserir o novo elemento - Se timeout é um valor positivo a operação bloqueia no máximo por timeout segundos até que gera a exceção Full caso não exista espaço dentro desse tempo. Queue.put_nowait(item) Equivalente a put(item, False). 5

Outros métodos das classes Queue: Queue.get(block=True, timeout=none) - Remove e devolve um item da queue. Se block é true e timeout é None (valores de omissão), a operação bloqueia se necessário até haver um item disponível. - Se timeout é um valor positivo a operação bloqueia no máximo timeout segundos, gerando a exceção Empty se não existe um item disponível nesse intervalo de tempo. Queue.get_nowait() Equivalente a get(false). 6

Outros métodos das classes Queue: Queue.task_done() - Indique que a tarefa retirada anteriormente da fila está completa. - Operação usada por threads que consomem elementos da Queue. - Para cada get(), deve haver uma chamada de task_done(), assinalando à fila que o processamento da tarefa está completo. Queue.join() - Bloqueia até que todos os itens da fila tenham sido processados, O contador de itens é incrementado sempre que um item é adicionado e decrementado sempre que é invocado task_done(). Quando o contador chega a 0 o join() desbloqueia. 7

Exemplo: como colocar numa Queue um conjunto de tarefas def worker(): while True: item = q.get() if item is None: break do_work(item) q.task_done() 8

Exemplo: como colocar numa Queue um conjunto de tarefas q = queue.queue() threads = [] for i in range(num_worker_threads): t = threading.thread(target=worker) t.start() threads.append(t) for item in source(): q.put(item) # block until all tasks are done q.join() 9

Exemplo: como colocar numa Queue um conjunto de tarefas # stop workers for i in range(num_worker_threads): q.put(none) for t in threads: t.join() 10

Exemplo: produtor / consumidor from queue import Queue import time import random class producer(thread): def init (self, queue): Thread. init (self) self.queue = queue def run(self) : for i in range(10): item = random.randint(0, 256) self.queue.put(item) print ('Producer notify : item N %d appended to queue by %s \n % (item, self.name)) time.sleep(1) 11

Exemplo: produtor / consumidor class consumer(thread): def init (self, queue): Thread. init (self) self.queue = queue def run(self): while True: item = self.queue.get() print ('Consumer notify : %d popped from queue by %s'\ % (item, self.name)) self.queue.task_done() 12

Exemplo: produtor / consumidor if name == ' main ': queue = Queue() t1 = producer(queue) t2 = consumer(queue) t3 = consumer(queue) t1.start() t2.start() t3.start() t1.join() t2.join() t3.join() Exercício: implementar, executar, modificar para terminar consumidor. 13

Exemplo: Dining Philosophers (by Edsger Dijkstra) Cinco filósofos, Aristotle, Kant, Spinoza, Marx, e Russell (tasks) gastam o seu tempo a pensar e a comer esparguete. Comem numa mesa redonda com 5 lugares. Para comer, cada filósofo precisa 2 garfos (resources). Existem cinco garfos na mesa, um à direita e um à esquerda de cada lugar. Quando um filósofo que vai comer não consegue pegar nos dois garfos, fica em espera. Comer demora um tempo aleatório, após o qual o filósofo pousa os dois garfos e vai pensar. Após passar um tempo aleatório a pensar sobre a natureza do universo, ele vai novamente comer.. 14

Exemplo: Dining Philosophers (by Edsger Dijkstra) Uma primeira hipótese de solução em python 15

Exemplo: Dining Philosophers (by Edsger Dijkstra) import threading import random import time class Philosopher(threading.Thread): running = True # variável de classe def init (self, name, forkonleft, forkonright): threading.thread. init (self) self.name = name self.forkonleft = forkonleft self.forkonright = forkonright 16

Exemplo: Dining Philosophers (by Edsger Dijkstra) def run(self): while(self.running): # Philosopher is thinking. time.sleep( random.uniform(3,13)) print '%s is hungry.' % self.name self.dine() 17

Exemplo: Dining Philosophers (by Edsger Dijkstra) def dine(self): self.forkonleft.acquire() self.forkonright.acquire() self.dining() self.forkonleft.release() self.forkonright.release() O que acontece se cada Filósofo, pega no garfo à sua direita? def dining(self): print '%s starts eating '% self.name time.sleep(random.uniform(1,10)) print '%s finishes eating and leaves to think.' % self.name 18

Exemplo: Dining Philosophers (by Edsger Dijkstra) def DiningPhilosophers(): forks = [threading.lock() for n in range(5)] philosophernames = ('Aristotle','Kant','Buddha','Marx', 'Russel') philosophers= [Philosopher(philosopherNames[i], forks[i%5], \ forks[(i+1)%5]) for i in range(5)] random.seed(507129) Philosopher.running = True for p in philosophers: p.start() time.sleep(100) Philosopher.running = False Print( ***Now we're finishing.") DiningPhilosophers() testar 19

Exemplo: Dining Philosophers (by Edsger Dijkstra) Resolver o deadlock: def dine(self): fork1, fork2 = self.forkonleft, self.forkonright while self.running: fork1.acquire(true) locked = fork2.acquire(false) if locked: break fork1.release() print ('%s swaps forks' % self.name) fork1, fork2 = fork2, fork1 else: return self.dining() fork2.release() fork1.release() Se conseguiu os 2 locks, segue para self.dining() Se não conseguiu, o 2º lock, liberta o primeiro, e troca os locks, continuando a tentar 20

X = Lock(). Exemplo: Dining Philosophers (by Edsger Dijkstra) x.acquire( blocking=true, timeout=-1) - Adquire o lock, de forma bloqueante ou não bloqueante. - Quando é invocado com blocking = True (valor de omissão) bloqueia até que o lock seja libertado e devolve True. - Quando invocado com blocking = False, não bloqueia. Se consegue adquire o lock devolve True, caso contrário devolve False 21

Estrutura: while valor: Exemplo: Dining Philosophers (by Edsger Dijkstra) else: if something: break return # executado, quando valor == False se não ocorreu o break 22

Exemplo: Readers and Writers a) Construa uma classe em RW, que possua um campo inteiro, XPTO, e dois métodos: ler e escrever. O método ler deve devolver o valor da variável XPTO; o método escrever deve adicionar o valor 100 à variável XPTO e seguidamente subtrair o mesmo valor à variável XPTO. b) Pretende-se que um objecto da classe RW seja partilhado por vários processos (Threads) de dois tipos: - processos Leitores que lêem o valor da variável XPTO usando o método ler; - processos Escritores que alteram a variável XPTO usando o método escrever. - Construa as classes Leitor e Escritor. Cada uma destas classes deve ter uma Thread de execução própria em que, num ciclo infinito, vão respectivamente lendo e alterando valores do objecto partilhado. 23

Exemplo: Readers and Writers c) Construa uma classe de teste que crie um objecto do tipo RW, 3 objectos do tipo Leitor e 2 objectos do tipo Escritor. Estude o comportamento do seu programa. Código RW.py d) Pretende-se que modifique as classes anteriores tal que os vários processos Leitores possam executar concorrentemente o método ler, mas que quando um processo Escritor executar o método escrever o faça em exclusão mútua. Isto é, quando um processo está a escrever, nenhum outro pode em simultâneo ler ou escrever a variável XPTO. 24

Exemplo: Readers and Writers Código rwsync.py import threading import time import random class RW(): def init (self): self.cond = threading.condition() self.nl = 0 self.xpto = 0 def ler (self): time.sleep(random.uniform(1,3)) return self.xpto 25

Exemplo: Readers and Writers def escrever (self): self.cond.acquire() while ( self.nl > 0): self.cond.wait() self.xpto += 100 time.sleep(random.uniform(1,3)) self.xpto -= 100 self.cond.release() 26

Exemplo: Readers and Writers def startler(self): self.cond.acquire() self.nl += 1 self.cond.release() def endler (self): self.cond.acquire() self.nl -= 1 if (self.nl == 0): self.cond.notifyall() self.cond.release() 27

Exemplo: Readers and Writers class Leitor(threading.Thread): def init (self, rw): treading.thread. init (self) self.rw = rw def run (self): while (True): self.rw.startler() if (self.rw.ler()!= 0): print ( Secção crítica violada ) self.rw.endler() 28

Exemplo: Readers and Writers class Escritor(threading.Thread): def init (self, rw): threading.thread. init (self) self.rw = rw def run (self): while (True): self.rw.escrever() 29

Exemplo: Readers and Writers if name == " main ": x = RW() l1 = Leitor(x) l2 = Leitor(x) l3 = Leitor(x) e1 = Escritor(x) e2 = Escritor(x) l1.start() l2.start() l3.start() e1.start() e2.start() 30

Execução sequencial versus multithreading from threading import Thread import urllib.request import time #ExecuçãoSequencial class nothreads_object(object): def run(self): function_to_run() Performance def non_threaded(num_iter): funcs = [] for i in range(int(num_iter)): funcs.append(nothreads_object()) for i in funcs: i.run() 31

Execução sequencial versus multithreading #execução multithreaded class threads_object(thread): def run(self): function_to_run() Performance def threaded(num_threads): funcs = [] for i in range(int(num_threads)): funcs.append(threads_object()) for i in funcs: i.start() for i in funcs: i.join() 32

Performance Execução sequencial versus multithreading def show_results(func_name, results): print ("%-23s %4.6f seconds"% (func_name, results)) def function_to_run(): #Fibonacci a = 0 b = 1 for i in range (100000): a = b b = a + b 33

Performance if name == " main ": num_threads = [ 1, 2, 4, 8 ] print('starting tests') for i in num_threads: start = time.time() non_threaded (i) executiontime = time.time() - start show_results("non_threaded (%s iters)" % i, executiontime) start = time.time() threaded (i) executiontime = time.time() - start show_results("threaded (%s threads)" % i, executiontime) print ('Iterations complete') 34

Performance - Estudar o comportamento do programa com a função da página 28 (Fibonacci) - Alterar o código para dado um número de execuções, o programa calcular o tempo médio de execução para cada uma das situações estudadas (1, 2, 4, 8 threads / iterações) - Que código é mais rápido, sequencial ou multi-threading? 35

Performance Estudar os tempos de execução para as seguintes funções: a) def function_to_run(): for i in range(10): with urllib.request.urlopen("https://google.com")as f: f.read(1024) 36

Performance Estudar os tempos de execução para as seguintes funções: b) def function_to_run(): file = open ("test.dat", "rb") size = 1024 for i in range (1000): file.read(size) 37