Laboratório de Programação II: Threads

13
Threads Threads Prof. Alex Camargo [email protected] UNIVERSIDADE FEDERAL DO PAMPA CAMPUS BAGÉ LABORATÓRIO DE PROGRAMAÇÃO II

Transcript of Laboratório de Programação II: Threads

ThreadsThreads

Prof. Alex [email protected]

UNIVERSIDADE FEDERAL DO PAMPACAMPUS BAGÉ

LABORATÓRIO DE PROGRAMAÇÃO II

Threads

Threads (processos leves) são processos que compartilham o contexto. De uma forma simples, pode-se pensar em threads como sendo funções dentro de um mesmo programa e que podem ser executadas concorrentente.

Um processo tradicional é igual a um processo com uma única thread.

Diferentes threads de um mesmo processo podem ser alocadas em processadores diferentes se a máquina for multiprocessada.

Laboratório de Programação II – Threads

Vantagens

As vantagens de se utilizar threads ao invés de várias instâncias do mesmo programa são:

Economia de recursos: utilizando threads não é necessário replicar a seção de código e dados para cada processo.

Velocidade: a troca de contexto é muito mais rápida.

Comunicação: como as threads compartilham a mesma área de dados, a comunicação entre as threads é simples e eficiente.

Laboratório de Programação II – Threads

As threads fornecem uma maneira bastante eficiente de se conseguir paralelismo em máquinas multiprocessadas.

Threads de Kernel e Usuário

Os tipos básicos de threads são:

Threads do kernel: threads admitidas diretamente pelo kernel.

Threads do usuário: gerenciamento de thread feito pela biblioteca de threads em nível de usuário.

Laboratório de Programação II – Threads

O Linux possui uma API para manipulação de threads implementada usando o padrão POSIX.

Para usar esta API, precisamos incluir o arquivo de cabeçalho <pthread.h> e linkar com a biblioteca -lpthread

Função pthread_create

Para criarmos uma thread, utilizamos a função pthread_create:

pthread_create(&pthread_id, NULL, &funcao, NULL);

pthread_id: ponteiro para uma variável do tipo pthread_t, que conterá o identificador (ID) da thread recém criada.

NULL (segundo parâmetro): 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.

funcao: um ponteiro para a função a ser executada pela thread.

NULL (último parâmetro): um void* que é passado como argumento para rotina (pthread_t). Use NULL se não for passar nenhum parâmetro.

Laboratório de Programação II – Threads

Passando dados

Para passarmos dados para uma thread, utilizamos o parâmetro void*. A melhor maneira de passarmos os dados é definir uma estrutura e passar um ponteiro para este tipo de estrutura:

Laboratório de Programação II – Threads

Passando dados

A função de thread precisa converter o void* em thread_alfa:

Laboratório de Programação II – Threads

Passando dados

Já no programa principal:

Laboratório de Programação II – Threads

Joining

O programa principal executa de forma concorrente com as threads. Se quisermos que programa principal espere até que uma thread tenha concluído, utilizamos a função pthread_join:

pthread_join(thread_id, NULL);

Se o segundo parâmetro não for NULL, ele receberá o valor de retorno da função de thread.

Enquanto a função join não for chamada, a thread fica em um estado ‘zumbi’, pois ela precisa guardar o valor de retorno. Após a chamada de pthread_join, os recursos da thread são liberados.

Laboratório de Programação II – Threads

Encerramento

Uma thread pode ser encerrada de várias formas:

Quando a função de thread é encerrada (return).

Quando é chamada a função pthread_exit(NULL).O parâmetro é o retorno da thread (pode ser NULL se o retorno for ignorado).

Laboratório de Programação II – Threads

É sempre preferível encerrar uma thread naturalmente do que cancelá-la a força.

Exemplo - Hello World

Laboratório de Programação II – Threads

Atividade 5 (2 pontos da A4)

1. Faça um programa que possua uma função (procedimento) de thread que verifique se um inteiro é par ou impar (desconsiderar o zero). Esta função recebe como parâmetro o inteiro (n) e mostra para o usuário "Par" ou "Impar". O programa principal lê (n) do teclado, cria uma thread para a função parimpar (passando o n), aguarda até que ela seja concluída (join).

2. Faça um programa que cria duas threads. Ambas recebem como parâmetro um ponteiro para a estrutura thread_alfa, vista anteriormente, e chamam a mesma função func, também vista anteriormente. Uma thread deve imprimir 300 ‘a’, e a outra 200 ‘z’ (estes valores e caracteres são passados através de um ponteiro para thread_alfa). O programa principal simplesmente espera as threads terminarem (join) e encerra. Repare para as threads recebendo ponteiros para estruturas e concorrendo pelo processador.Dica: Dentro da função, converta o void* valores recebido para thread_alfa: thread_alfa* p = (thread_alfa*) valores;

Cada grupo deverá submeter via Moodle UM arquivo compactado (Grupo_0.zip) contendo a implementação em C até o final da aula de 08/08.

Laboratório de Programação II – Threads

Referências

Barney, B. POSIX Threads Programming. Lawrence Livermore National Laboratory.

Heinen, M. R. Programação Avançada em C no GNU/Linux. Capítulo 04: Threads. UNISINOS.

Laboratório de Programação II – Threads