41
Linguagem de Programação I Carlos Eduardo Batista Centro de Informática - UFPB [email protected]

Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Linguagem de Programação I

Carlos Eduardo Batista !

Centro de Informática - UFPB [email protected]

Page 2: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

● Exemplo: ◦ Explorar Templates e Exceções ◦ Incrementar com o uso de STL

"2

Page 3: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Exercícios

● Crie uma função verificarPalindromo() que recebe um vetor como parâmetro. Ela deve retornar true se ele contém um palíndromo e false caso contrário. ◦ Exemplo: Um vetor contendo 1, 2, 3, 2, 1 é um palíndromo. E

um vetor contendo 1, 4, 3, 2, 1 não é um palíndromo. !

● Crie uma mapa que associa o nome de uma pessoa a um objeto do tipo Pessoa. A classe Pessoa deve ser feita usando templates, armazenando uma variável de tipo arbitrário. Crie um programa que leia entradas e armazene utilizando a classe map. Caso o usuário tente cadastrar uma chave duplicada, uma exceção deve ser lançada.

"3

Page 4: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Processo x thread

● Processo - Um conjunto de recursos necessários para a execução duma programa. ◦ um espaço de endereçamento (virtual address space) que contêm o texto do programa e os seus dados ◦ uma tabela de descritores de arquivos abertos ◦ informação sobre processos filhos ◦ código para tratar sinais (signal handlers) ◦ informação sobre o próprio etc.

"4

Page 5: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Processo x thread

● Uma linha ou contexto de execução, chamada “Thread” ◦ Uma thread tem um programa counter (pc) que guarde informação sobre a próxima instrução a executar ◦ Registadores – valores das variáveis atuais ◦ Stack – contem a história de execução com um “frame” para cada procedimento chamado mas não terminado

"5

Page 6: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Criação de processos

O processo filho é uma cópia exata do processo que chama a rotina fork(), sendo a única diferença um identificador de processo (pid) diferente

pid = fork() if (pid == 0) código executado pelo filho else código executado pelo pai if (pid == 0) exit (0); else wait (0); //esperar pelo filho .. JOIN

Programa principal

FORK

JOIN

FORK

FORK

JOIN JOIN JOIN

Spawned processes

paifilho e pai do

Inter Process Communication –

Pipes, Shared Memory, Signal etc.

Page 7: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

realidade

conceito

context switch

Page 8: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

O modelo de threads

● Os dois conceitos necessários para a execução dum programa, “conjunto de recursos” e “contexto de execução” podem ser separados:

● Processos são usados para agrupar recursos.

● Threads são as entidades escalonadas para execução no CPU.

"8

Page 9: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Processos versus Threads

Arquivos

IP

CódigoHeap

Rotinas de interrupção

Heavyweight Process: programas completamente separados com suas próprias variáveis, pilha e alocação de memória

Arquivos

IPCódigo

Heap

Rotinas de interrupçãoIP

Threads: lightweight processes rotinas compartilham o mesmo espaço de memória e variáveis globais

stack

stack

stack

Page 10: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Processos versus Threads

• Program Counter • Address Space

• Stack • Global Variables • Register Set • Open Files

• Child Threads • Child Processes

• State (ready,blocked ..) !

• Timers

• Signals

• Semaphores

• Accounting Information

Per Thread Items Per Process Items

Page 11: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

realidade

conceito

context switch

0

high

codigo biblioteca

dados

registers

CPU

R0

Rn

PC

“memoria”

x

x

Text programacommon runtime

stack

address space

SPy

y stack

Thread Em execução

Thread pronto para executar

Environ $USER=A1

Page 12: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads x processos

● A criação e terminação duma thread nova é em geral mais rápida do que a criação e terminação dum processo novo.

● A comutação de contexto entre duas threads é mais rápido do que entre dois processos.

● A comunicação entre threads é mais rápida do que a comunicação entre processos - porque as threads compartilham tudo: espaço de endereçamento, variáveis globais etc.

● Multi-programação usando o modelo de threads é mais simples e mais portável do que multi-programação usando múltiplos processos.

"12

Page 13: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Implementação

● Existem duas abordagens principais para a implementação de threads.

● Kernel-level Threads -- System Calls. ● User-Level Threads -- Thread Libraries. ● Existem vantagens e desvantagens em

ambos os casos.

"13

Page 14: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Kernel threads

● Vantagens ◦ O kernel pode simultaneamente escalonar várias threads do mesmo processo em vários processadores (reais ou virtuais) ◦ As rotinas do próprio kernel podem aproveitar threads.

● Desvantagens: ◦ A troca entre threads implica ações do kernel e isto tem um custo que pode ser significativo.

"14

Page 15: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

User level threads

● Vantagens ◦ A troca de Threads não envolve o kernel ◦ Não há o custo adicional de execução do kernel ◦ O OS não precisa de oferecer apoio para threads – portanto é mais simples. ◦ Escalonamento pode ser especifico para uma aplicação ◦ Uma biblioteca pode oferecer vários métodos de escalonamento portanto uma

aplicação poderá escolher o algoritmo melhor para ele. ◦ ULTs podem executar em qualquer SO ◦ As bibliotecas de código são portáveis

● Desvantagens ◦ Muitas das chamadas ao sistema são “bloqueantes” e o kernel bloqueia

processos – neste caso todos as threads dum processo podem ser bloqueados.

◦ O kernel vai atribuir o processo a apenas um CPU portanto duas threads dentro do mesmo processo não podem executar simultaneamente numa arquitetura com múltiplas processadores

"15

Page 16: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Pthreads

● POSIX 1003.1-2001 – pthreads ● API para gerenciamento de threads ◦ >more /usr/include/pthread.h ◦ > man pthread_create

● Threads co-existem num mesmo processo, compartilhando vários recursos, mas são escalonadas separadamente pelo sistema operacional

● Somente o mínimo necessário de recursos é replicado entre duas threads

"16

Page 17: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Visão geral

Sem Threads Com Threads

Page 18: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Pthreads

Interface portável do sistema operacional, POSIX, IEEE

Programa principal

pthread_create( &thread1, NULL, proc1, &arg);

pthread_join( thread1, NULL ou *status);

thread1

proc1(&arg); {

return(&status); }

Código da thread

Page 19: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

PThread APIPrefix Funcionality

pthread_ Threads themselves and miscellaneous subroutines

pthread_attr_ Thread attributes objects

pthread_mutex_ Mutexes

pthread_mutexattr_ Mutex attributes objects

pthread_cond_ Condition variables

pthread_cond_attr Condition attributes objects

pthread_key_ Thread-specific data keys

Page 20: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Como programar

● Usar ◦ #include “pthread.h”

● Compilar com a opção –pthread ◦ gcc –pthread ex_pthread.c –o ex_pthread

Page 21: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Criando uma thread

int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);

Page 22: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

pthread_create

#include <stdio.h> #include <stdlib.h> #include <pthread.h> void *print_message_function( void *ptr ); main() { pthread_t thread1, thread2; char *message1 = "Thread 1“, *message2 = "Thread 2"; int iret1, iret2; iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1); iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2); pthread_join( thread1, NULL); pthread_join( thread2, NULL); printf("Thread 1 returns: %d\n",iret1); printf("Thread 2 returns: %d\n",iret2); exit(0); } void *print_message_function( void *ptr ) {

char *message; message = (char *) ptr;

printf("%s \n", message); }

Page 23: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Encerrando uma thread

● Além da alternativa de simplesmente encerrar a função, é possível também ◦ void pthread_exit(void *retval);

Page 24: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Pthread Join

● A rotina pthread_join() espera pelo término de uma thread específica !for (i = 0; i < n; i++) pthread_create(&thread[i], NULL, (void *) slave,

(void *) &arg); !...thread mestre !for (i = 0; i < n; i++) pthread_join(thread[i], NULL);

Page 25: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Detached Threads (desunidas)

Pode ser que uma thread não precisa saber do término de uma outra por ela criada, então não executará a operação de união. Neste caso diz-se que o thread criado é detached (desunido da thread pai progenitor)

Programa principal

pthread_create();

pthread_create();

Thread

pthread_create();Thread

Thread Término

TérminoTérmino pthread_exit

Page 26: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Pthreads

● Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais poderá ser necessário sincronizar o acesso a este variavel para evitar problemas.

● Código nestas condição diz-se “uma seção critica” ◦ Por exemplo, quando dois ou mais threads podem

simultaneamente incrementar uma variável x ◦ /* codigo – Seção Critica */ ◦ x = x +1 ;

● Uma seção crítica pode ser protegida utilizando-se pthread_mutex_lock() e pthread_mutex_unlock()

"26

Page 27: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Mutex

/* Note scope of variable and mutex are the same */ pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; int counter=0; !/* Function C */ void functionC() { pthread_mutex_lock( &mutex1 ); counter++ pthread_mutex_unlock( &mutex1 ); }

Page 28: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Fontes de problemas

● Condição de corrida ◦ Não assuma uma ordem específica para a execução das threads ◦ Um código pode funcionar muito bem em determinados momentos e gerar sérios problemas em outros

● Thread safe code ◦ Use bibliotecas que possuam chamadas “thread safe” ◦ Várias chamadas à mesma função devem ser permitidas

● Deadlock

Page 29: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

● Biblioteca padrão STD passou a incluir suporte a threads

● Criação e gerência do ciclo de vida de threads

● #include <thread> ● Compilador deve suportar C++11 ◦ Opções -std=c++0x" ou "-std=c++11" no G++ para ativar suporte

Page 30: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <iostream> // std::cout #include <thread> // std::thread !void foo() { std::cout << “foo!” << endl; } !void bar(int x) {std::cout << “bar: ” << x << endl; } !int main() { std::thread first (foo); // spawn new thread that calls foo() std::thread second (bar,10); // spawn new thread that calls bar(10) ! std::cout << "main, foo and bar now execute concurrently...\n"; ! // synchronize threads: first.join(); // pauses until first finishes second.join(); // pauses until second finishes ! std::cout << "foo and bar completed.\n"; ! return 0; }

Page 31: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

class thread { public: class id; typedef /*implementation-defined*/ native_handle_type; ! thread() noexcept; template <class F, class ...Args> explicit thread(F&& f, Args&&... args); ~thread(); thread(const thread&) = delete; thread(thread&&) noexcept; thread& operator=(const thread&) = delete; thread& operator=(thread&&) noexcept; void swap(thread&) noexcept; bool joinable() const noexcept; void join(); void detach(); id get_id() const noexcept; native_handle_type native_handle(); static unsigned hardware_concurrency() noexcept; };

Page 32: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

this_thread provide functions that access current the thread of execution

yield!(C++11)

suggests that the implementation reschedule execution of threads (function)

get_id!(C++11)

returns the thread id of the current thread (function)

sleep_for!(C++11)

stops the execution of the current thread for a specified time duration (function)

sleep_until!(C++11)

stops the execution of the current thread until a specified time point (function)

Page 33: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <thread> #include <iostream> #include <vector> !void hello(){ std::cout << "Hello from thread “; std::cout << std::this_thread::get_id() << std::endl; } !int main(){ std::vector<std::thread> threads; for(int i = 0; i < 5; ++i){ threads.push_back(std::thread(hello)); } for(auto& thread : threads){ thread.join(); } return 0; }

Page 34: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <thread> #include <iostream> class TestClass { int i; public: TestClass(int n) { i = n; } void greeting(std::string const& message) const { std::cout << message << std::endl; std::cout << "My number: " << n << std::endl; } }; int main() { TestClass x(10); std::thread t(& TestClass::greeting,&x,"Hello! "); t.join(); }

Page 35: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include ... !int main() { std::shared_ptr<SayHello> p(new SayHello); std::thread t(&SayHello::greeting,p,"goodbye"); t.join(); } !// What if you want to pass in a reference to an // existing object, and a pointer just won't do? // That is the task of std::ref.

Page 36: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <thread> #include <iostream> !void write_sum(int x,int y) { std::cout<<x<<" + "<<y<<" = "<<(x+y)<<std::endl; } !int main() { std::thread t(write_sum,123,456); t.join(); }

Page 37: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <thread> #include <iostream> #include <functional> // for std::ref class PrintThis { public: void operator()() const { std::cout<<"this="<<this<<std::endl; } }; int main() { PrintThis x; x(); std::thread t(std::ref(x)); t.join(); std::thread t2(x); t2.join(); }

/* this=0x7fffb08bf7ef this=0x7fffb08bf7ef this=0x42674098 */

Page 38: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

#include <thread> #include <iostream> #include <functional> !void increment(int& i) { ++i; } !int main() { int x=42; std::thread t(increment,std::ref(x)); t.join(); std::cout<<"x="<<x<<std::endl; }

Page 39: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Threads STD (C++11)

● Leitura complementar ● http://cppwisdom.quora.com/Why-

threads-and-fork-dont-mix ● http://www.linuxprogrammingblog.com/

threads-and-fork-think-twice-before-using-them

Page 40: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Referências

● Notas de aula – Claudio Esperança e Paulo Cavalcanti (UFRJ)

● Notas de aula – Allan Lima (citi/UFPE)

"40

Page 41: Linguagem de Programação Iwiki.cbatista.net/lib/exe/fetch.php/lpi-aula16-threads-b.pdf · Quando dois ou mais threads podem simultaneamente alterar às mesmas variaveis globais

Linguagem de Programação I

Carlos Eduardo Batista !

Centro de Informática - UFPB [email protected]