Você está na página 1de 18

Informática industrial

Threads

Prof. Guilherme Márcio Soares, Dr. Eng.


guilherme.marcio@ufjf.edu.br

Pedro de Assis Sobreira Jr.


Introdução
❑ O que é um processo?

❑ Linhas de execução (Threads)

❑ Utilização de Threads em C#

❑ Sincronismo

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 2


Processo
❑ Pode ser definido como um módulo executável do programa.

❑ Pode ocorrer de forma concorrente com outros processos.

❑ Deve ser um entidade independente, como seu próprio fluxo de controle e


estado interno.

❑ É uma unidade de software mais pesada

Aguardando clientes TCP Leitura dados sensor


(tarefa bloqueante)

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 3


Thread (Linha de execução)
❑ Possibilitam a programação multitarefa;

❑ Possibilitam a execução de várias tarefas em paralelo:

❑ Processo pode ser subdividido em várias tarefas que serão


executadas concorrentemente.

❑ Normalmente é um fluxo de execução independente dentro de um


processo.

❑ Pode ser entendida como um processo mais leve que irá rodar de
maneira simultânea.

Aguardando clientes TCP Leitura dados sensor


(tarefa bloqueante)

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 4


Processo vs Thread

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 5


Thread (Linha de execução)

Programa com 1 linha de


execução
Aguardando clientes TCP Leitura dados sensor
(tarefa bloqueante)

Aguardando clientes TCP

Programa com 2 linhas


de execução
Leitura dados sensor

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 6


Estados de uma Thread

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 7


Utilização de Threads em C#
❑ As classes relacionadas às “Threads” estão localizadas no namespace
System.Threading.

❑ Classe Thread é utilizada para criar e controlar uma Thread.

❑ O método Thread.Join() pode ser utilizado para sincronizar uma


determinada execução.

❑ O construtor requere um delegate, que pode ser:

❑ delegate void ThreadStart(void) – quando não é necessário passar


parâmetros para a Thread;

❑ delegate void ParameterizedThreadStart (object obj) – quando é


necessário passar parâmetros;

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 8


Exemplo 1
Tipo: Button Tipo: Label
(Name): bt_cont (Name): lb_st

Tipo: Button
(Name): bt_print
Tipo: ListBox
(Name): lst_print

❑ Parte 1 – comando bloqueante


❑ Parte 2 – uso da classe Thread
❑ Parte 3 – uso do delegate ThreadStart
❑ Parte 4 – uso do delegate ParameterizedThreadStart

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 9


Compartilhamento de recursos
❑ Muitas vezes as diversas Threads de um programa podem compartilhar
recursos;

❑ Dependendo das características do programa, estas diversas linhas de


execução podem tentar acessar um recurso de forma simultânea e
possivelmente pode corrompê-lo ou fazer com que o programa não se
comporte da maneira esperada.

❑ Exemplo: ThreadSincronismo – Parte 1

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 10


Sincronismo
❑ Desta forma é necessário proteger recursos compartilhados.

❑ Existem diversas formas de se fazer sincronismo em sistemas


concorrentes:

❑ Seção Crítica;
❑ Monitor;
❑ Mutex;
❑ Semáforo;
❑ Produtor-Consumidor;
❑ Etc;

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 11


Seção Crítica
❑ Os compartilhados que devem ser protegidos podem ser agrupados em
regiões chamadas seções críticas.

❑ Estas seções críticas devem possuir comportamento atômico, ou seja,


as instruções não podem ser interrompidas por outra Thread.

❑ Em C# pode-se utilizar a instrução lock para marcar uma seção crítica.

❑ Para sua utilização é necessário criar um objeto que será bloqueado


pela Thread assim que ela desejar executar as instruções da seção
crítica. Quando terminar a execução desta seção, o objeto é liberado e
outra Thread poderá acessar a seção crítica.

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 12


Seção Crítica
❑ Normalmente cria-se um objeto do com os especificadores private e
static.

❑ Uma Thread que tentar bloquear um objeto que já esteja bloqueado irá
dormir até que tal objeto seja liberado.

❑ Exemplo: Seção Crítica com lock

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 13


Classe Monitor
❑ A palavra chave lock na verdade é um caminho mais rápido para a
implementação da seção crítica. A classe Monitor permite realizar a
mesma tarefa utilizando os métodos Monitor.Enter() e Monitor.Exit();

❑ É importante ressaltar que apenas a Thread que adquiriu o recurso do


objeto bloqueado (lock ou Monitor.Enter()) é que pode liberar tal recurso
(Monitor.Exit()).

❑ A classe Monitor ainda possui outros métodos importantes, como o


Monitor.Wait(), que pode colocar uma Thread em estado de espera.

❑ Exemplo: Seção Crítica com Monitor

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 14


Classe Mutex
❑ Em C#, a classe Mutex possui funcionalidades muito similares ao lock(). No
entanto, ela pode ser utilizada para realizar o sincronismo de Threads em mais
de um processo.

❑ Em outras palavras, enquanto a ação do comando lock é restrita à aplicação, o


Mutex permite uma ação mais abrangente, incluindo outros aplicativos.

❑ É importante ressaltar a aquisição e liberação de um recurso utilizando a classe


Mutex é cerca de 50 vezes mais lenta do que a mesma ação utilizando o comando
lock.

❑ Na classe Mutex, a aquisição do recurso é realizada através do método


Mutex.WaitOne, e a liberação do recurso através do método
Mutex.ReleaseMutex. O recurso também é liberado se o objeto Mutex for
destruído.

❑ Assim como o lock ou o Monitor, a liberação dos recursos só pode ser realizada
pela Thread que os adquiriu.

❑ Exemplo: Mutex

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 15


Semáforo
❑ Um semáforo é utilizado quando se deseja limitar o número de Threads
que podem executar uma determinada parte do código.

❑ Ele pode se entendido como um “segurança” de um ambiente cuja


capacidade é limitada. Desta forma, se o ambiente estiver cheio,
ninguém poderá entrar a menos que alguém saia do local.

❑ O semáforo implementa uma fila de Threads. Por exemplo, se 4 Threads


desejarem executar uma parte do código que possui um semáforo com 2
tokens, duas Threads irão executar tal código, enquanto que 2 irão
esperar a liberação de recursos para poderem executar tais instruções.

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 16


Semáforo
❑ Diferentemente do lock, Monitor e Mutex, qualquer Thread pode liberar
recursos do semáforo, uma vez que este não possui um “dono”.

❑ Em C#, existem 2 classes possíveis, a Semaphore e a SemaphoreSlim. A


diferença principal é que a Semaphore permire a sincronização inter-
processos e a SemaphoreSlim não. Por outro lado, a classe
SemaphoreSlim possui um tempo de aquisição e liberação de recursos
menor.

❑ Os métodos utilizados para a aquisição e liberação de recursos são o


Semaphore.Wait() e o Semaphore.Release(), respectivamente.

❑ Ex.: Semaphore

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 17


Exemplo Thread
❑ Melhorar o servidor da calculadora remota de modo que ela possa
atender vários clientes simultaneamente.

Prof. Guilherme Márcio Soares Informática Industrial – ENE 118A 18