












Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Threads em c++
Tipologia: Notas de estudo
1 / 20
Esta página não é visível na pré-visualização
Não perca as partes importantes!













P r i m e i r a t e n t a t i v a :
P r o g r a m a d e e x e m p l o :
#include <windows.h> #include <stdio.h> #include <process.h>
typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)( LPVOID lpThreadParameter ); typedef unsigned *PBEGINTHREADEX_THREADID;
class ThreadObject { public: ThreadObject(); // Construtor void StartThread(); virtual DWORD WINAPI ThreadFunc(LPVOID param); void WaitForExit(); private: HANDLE m_hThread; // Handle para thread criada DWORD m_ThreadId; // Identificador da thread };
ThreadObject::ThreadObject() // Inicializa membros privados da classe { m_hThread = NULL; m_ThreadId = 0; }
void ThreadObject::StartThread() // Cria Thread { m_hThread = (HANDLE)_beginthreadex(NULL, 0, (PBEGINTHREADEX_THREADFUNC)ThreadFunc, 0, 0, (PBEGINTHREADEX_THREADID)&m_ThreadId ); if (m_hThread) { printf("Thread launched\n"); } }
void ThreadObject::WaitForExit() // Espera fim da thread { WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); }
S o l u ç ã o p a r a o p r o b l e m a :
m_hThread m_ThreadId
ThreadObject(); StartThread(); virtual ThreadFunc(); WaitForExit();
ThreadObject this param
param
Thread primária ThreadFunc
stack esperado por função membro não estática
stack construído por _beginthread…
ThreadFunc(param) se fosse chamada de função
_beginthreadex(ThreadFunc(param))
E x e m p l o : P r o g r a m a c o r r i g i d o
E s t r a t é g i a 1 : F u n ç ã o m e m b r o e s t á t i c a
// Só os .h mais básicos serão incluídos. #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <process.h>
typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)( LPVOID lpThreadParameter ); typedef unsigned *PBEGINTHREADEX_THREADID;
// // This ThreadObject is created by a thread that wants to start another // thread. All public member functions except ThreadFunc() are called // by that original thread. The virtual function ThreadMemberFunc() is // the start of the new thread. //
class ThreadObject { public: ThreadObject(); void StartThread(); void WaitForExit(); static DWORD WINAPI ThreadFunc(LPVOID param);
protected: virtual DWORD ThreadMemberFunc(); HANDLE m_hThread; DWORD m_ThreadId; };
ThreadObject::ThreadObject() // Aqui nada muda { m_hThread = NULL;
m_ThreadId = 0; }
void ThreadObject::StartThread() { m_hThread = (HANDLE)_beginthreadex(NULL, 0, (PBEGINTHREADEX_THREADFUNC) ThreadObject::ThreadFunc, (LPVOID)this, // passa pointer para objeto como parâmetro 0, (PBEGINTHREADEX_THREADID) &m_ThreadId );
if (m_hThread) { printf("Thread launched\n"); } }
void ThreadObject::WaitForExit() // Aqui nada muda { WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); }
// // This is a static member function. Unlike C static functions, you only // place the static declaration on the function declaration in the class, not on // its implementation. // Static member functions have no "this" pointer, but do have access rights. // DWORD WINAPI ThreadObject::ThreadFunc(LPVOID param) { // Use the param as the address of the object ThreadObject* pto = (ThreadObject*)param;
// Call the member function. Since we have a proper object pointer, even // virtual functions will be called properly.
return pto->ThreadMemberFunc(); }
// This above function ThreadObject::ThreadFunc() calls this function after // the thread starts up. DWORD ThreadObject::ThreadMemberFunc() // Função que desempenhará as funções da thread { // Do something useful ...
E x e m p l o : P r o g r a m a c o r r i g i d o
E s t r a t é g i a 2 : F u n ç ã o m e m b r o n o e s t i l o C
/*
// Só os .h mais básicos serão incluídos. #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <process.h>
// Work around the buggy _beginthreadex() prototype typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)( LPVOID lpThreadParameter ); typedef unsigned *PBEGINTHREADEX_THREADID;
// Define the prototype for the function used to start the thread. // Função no estilo C que chamrá a função membro DWORD WINAPI ThreadFunc(LPVOID param);
class ThreadObject { public: ThreadObject(); void StartThread(); void WaitForExit();
// A função membro deve ser declarada como pública ou a função no // estilo C não terá direitos de acessá-la. virtual DWORD ThreadMemberFunc();
protected: HANDLE m_hThread; DWORD m_ThreadId; };
ThreadObject::ThreadObject()
m_hThread = NULL; m_ThreadId = 0; }
void ThreadObject::StartThread() { m_hThread = (HANDLE)_beginthreadex(NULL, 0, (PBEGINTHREADEX_THREADFUNC) ThreadFunc, (LPVOID)this, 0, (PBEGINTHREADEX_THREADID) &m_ThreadId );
if (m_hThread) { printf("Thread launched\n"); } }
void ThreadObject::WaitForExit() { WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); }
// Esta função é chamada quando a thread inicia DWORD WINAPI ThreadFunc(LPVOID param) { // Use the param as the address of the object ThreadObject* pto = (ThreadObject*)param; // Call the member function. Since we have a proper object pointer, even // virtual functions will be called properly. return pto->ThreadMemberFunc(); }
// A função ThreadFunc() chama esta função assim que a thread inicia // DWORD ThreadObject::ThreadMemberFunc() { // Do something useful ... return 0; }
void main() { ThreadObject obj;
Construindo Seções críticas mais seguras
E x e m p l o : E n c a p s u l a n d o a d i r e t i v a c r i t i c a l s e c t i o n.
Class CriticalSection { public: CriticalSection(); // Construtor ~CriticalSection(); // Destrutor void Enter(); // Entra na seção crítica void Leave(); // Sai da seção crítica private: CRITICAL_SECTION m_CritSect; };
CriticalSection::CriticalSection() { InitializeCriticalSection(&m_CritSect); }
CriticalSection::~CriticalSection() { DeleteCriticalSection(&m_CritSect); }
CriticalSection::Enter() { EnterCriticalSection(&m_CritSect); }
CriticalSection::Leave() { LeaveCriticalSection(&m_CritSect); }
Class String { Public: String(); virtual ~String(); virtual void Set(char * str); int GetLength(); Private: CriticalSection m_Sync; char* m_pData; };
String::String() { // O construtor de m_Sync será chamado automaticamente já que se trata // de uma variável membro.. n_pData = NULL; }
String::~String() { m_Sync.Enter(); delete [] m_pData; m_Sync.Leave(); // O destrutor do membro de dado m_Sync será chamado // automaticamente }
void String::Set(char *str) { m_Sync.Enter(); delete [] m_pdata; // destrói string m_pdata = new char[::strlen(str)+1]; // aloca novo string ::strcpy(m_pData, str); // copia string m_Sync.Leave(); }
int String::GetLength() { if (m_pData == NULL) return 0; m_Sync.Enter(); int len = ::strlen(m_pData); m_Sync.Leave(); return len; }
Void String::Truncate(int length) { If (m_pData == NULL) return 0; // Ao declarar uma variável do tipo Lock o construtor será chamado // automaticamente. Lock lock(&m_Sync); if length >= GetLength()) { // pediu para truncar além do fim do string // lock efetuará limpeza automaticamente return; } m_pData[length] = ‘\0’; // lock efetuará limpeza automaticamente }
Critical Section Mutex Semáforo Binário
Vantagens
Desvantagens
Construindo Locks intercambiáveis:
~LockV2(); private: LokableObject* m_pLockable; // Objeto do tipo locker qualquer };
LockV2::LockV2(LockableObjetc* pLockable) { m_pLockablel = pLockable; m_pLockable->Lock(); }
Lock::~LockV2() { m_pLockable->Unlock(); }
Class String V2{ Public: StringV2(); virtual ~StringV2(); virtual void Set(char * str); int GetLength(); Private: // Escolhemos objeto do tipo seção crítica como variável de locker CriticalSectionV2 m_Lockable; // assegura limpeza automática char* m_pData; };
StringV2::StringV2() { // O construtor de m_Lockable será chamado automaticamente já que se // trata de uma variável membro.. n_pData = NULL; }
StringV2::~StringV2() { // O programa deve se assegurar que é seguro destruir o objeto delete [] m_pData; // O destrutor de m_Lockable será chamado automaticamente }
void StringV2::Set(char *str) { LockV2 localLock(&m_Lockable); // entra na seção crítica delete [] m_pdata; // destrói string m_pdata = NULL; m_pdata = new char[::strlen(str)+1]; // aloca novo string ::strcpy(m_pData, str); // copia string
// Quando o objeto sai de escopo, seu destrutor é chamado e ele // abandona a seção crítica }
int StringV2::GetLength() { LockV2 localLock(&m_Lockable); // entra na seção crítica if (m_pData == NULL) return 0; return ::strlen(m_pData); // sai da seção crítica }
Exercícios: