08.02.2015 Views

Programação Funcional e Concorrente com Scheme

Programação Funcional e Concorrente com Scheme

Programação Funcional e Concorrente com Scheme

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

notas de aula -<br />

Jerônimo C. Pellegrini<br />

A sincronização usando lightswitch descrita na seção 11.3.3 pode levar a starvation<br />

da thread escritora, que poderia ser indefinidamente preterida quando da disputa pelo<br />

lock. No entanto, as leitoras no pool de threads também removem itens da fila – e quando<br />

a fila estiver vazia, a thread escritora necessariamente conseguirá o lock.<br />

Para obter um item de trabalho, uma thread trabalhadora deve primeiro esperar até<br />

que haja itens disponíveis. Ela não pode excluir a thread produtora ainda, ou haveria<br />

um deadlock. Em seguida, havendo itens na fila, esta thread exclui a produtora e depois<br />

adquire exclusividade para obter o item de trabalho:<br />

( define get-work-item !<br />

( lambda ()<br />

( semaphore-wait ! * work-q-nonempty *)<br />

( enter-work-queue * work-q-no-getters *)<br />

( semaphore-wait ! * work-q-get-mutex *)<br />

( let (( item ( dequeue ! * work-queue *)))<br />

( semaphore-signal-by ! * work-q-get-mutex * 1)<br />

( leave-work-queue * work-q-no-getters *)<br />

item )))<br />

Depois de obter o item, a thread abre mão da exclusividade e sai da sala; se ela for a<br />

última a fazer um get, a thread produtora poderá entrar para adicionar itens.<br />

Para adicionar itens de trabalho, a thread produtora espera primeiro que não haja<br />

consumidoras, depois adiciona o item na fila. Em seguida, avisa as consumidoras que há<br />

mais um item disponível e permite que elas entrem:<br />

( define add-work-item !<br />

( lambda ( item )<br />

Versão Preliminar<br />

( semaphore-wait ! * work-q-no-getters *)<br />

( set ! * work-queue * ( enqueue ! * work-queue * item ))<br />

( semaphore-signal-by ! * work-q-nonempty * 1)<br />

( semaphore-signal-by ! * work-q-no-getters * 1)))<br />

Um worker retira um item de trabalho da fila, chama interage e fecha a porta TCP.<br />

Em seguida, re<strong>com</strong>eça <strong>com</strong> outro item de trabalho. Se a fila de trabalho estiver vazia, o<br />

worker ficará bloqueado.<br />

( define worker<br />

( lambda ()<br />

( let loop (( item ( get-work-item !)))<br />

[ 27 de outubro de 2010 at 15:47 ]<br />

261

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!