Skip to main content

Wielowątkowość – Event-Driven threads

W poprzednim artykule opisałem podstawowe zagadnienia z dziedziny wielowątkowości, a także wyjaśniłem zasadę działania wątków typu Worker.

Zapoznanie się z poprzednim artykułem jest fakultatywne ;D:
http://blog.kacki.pl/dev/worker-threads/.

Wstęp

Cała platforma bada opiera się o wielowątkowość typu Event-driven threads (opartej na zdarzeniach), gdzie aby zakończyć wątek, trzeba wysłać sygnał końca metodą Stop().
Dodatkowo wątki tego typu umożliwiają wysyłanie i odbieranie komunikatów do/z innych wątków (asynchroniczne operacje).

Tworzenie

Aby stworzyć wątek typu Event-Driven wystarczy wyprowadzić nową klasę dziedziczącą po klasie Thread. Dla przypomnienia hierarchia klas:

Klasa Thread posiada kilka metod wirtualnych, których implementacja jest opcjonalna.
Oto niektóre z nich:

virtual bool OnStart(void);
virtual void OnStop(void);
virtual Osp::Base::Object* Run(void);

OnStart() – Zdarzenie uruchomienia wątku.
OnStop() – Zdarzenie zatrzymania wątku.

Klasa Thread dostarcza domyślną implementację metody Run() z interfejsu IRunnablenie powinniśmy jej przesłaniać – jeśli to zrobimy, wątek będzie się zachowywał jak typu Worker i po wyjściu z tej metody wątek zostanie automatycznie zakończony.

Implementacja

/*
 * MyTask.h
 *
 *  Created on: 28-10-2011
 *      Author: markac
 */

#ifndef MYTASK_H_
#define MYTASK_H_

#include <FBase.h>

using namespace Osp::Base;
using namespace Osp::Base::Runtime;

class MyTask :
    public Thread
{
public:
	MyTask();
	virtual ~MyTask();

	virtual bool OnStart(void);
	virtual void OnStop(void);
};

#endif /* MYTASK_H_ */
/*
 * MyTask.cpp
 *
 *  Created on: 28-10-2011
 *      Author: markac
 */

#include "MyTask.h"

MyTask::MyTask() {
	// TODO Auto-generated constructor stub
}

MyTask::~MyTask() {
	// TODO Auto-generated destructor stub
}

bool MyTask::OnStart()
{
    // inicjalizacja zadania i uruchomienie
    return true;  // false - natychmiastowe zakończenie wątku
}

void MyTask::OnStop()
{
	// zwolnij zajęte zasoby
}

Uruchamianie

MyTask* pThread = new MyTask();
pThread->Construct(THREAD_TYPE_EVENT_DRIVEN);    // THREAD_TYPE_WORKER dla typu Worker
pThread->Start();

Zatrzymywanie

Aby zakończyć wątek, wywołujemy metodę Stop().

// zatrzymaj zadanie
pThread->Stop();  // tylko dla typu THREAD_TYPE_EVENT_DRIVEN

// czekaj na zakończenie zadania
pThread->Join();

// usuń wątek
delete pThread;
pThread = null;

Różnice między wątkami typu Worker i Event-Driven

Dobrze ilustruje to poniższy obrazek, który zdecydowałem się przytoczyć jeszcze raz.

Worker threads – po wykonaniu zadania w ciele metody Run(), wątek zostaje automatycznie zakończony.

Event-driven threads – wątek z obsługą zdarzeń/powiadomień, działający do chwili uzyskania sygnału zatrzymania metodą Stop().

Na tym różnice się nie kończą. Wątki typu Event-Driven posiadają obsługę zdarzeń/sygnałów odbieranych z innych wątków.
O komunikacji między wątkami będzie traktował jeden z kolejnych artykułów.

Podsumowanie

Aby stworzyć wątek typu Worker:

  1. Wyprowadzamy nową klasę implementującą interfejs IRunnable lub dziedziczącą po klasie Thread.
  2. Przesłaniamy metodę Run() i w ciele metody umieszczamy nasze zadanie.
  3. Zakończenie wątku nastąpi automatycznie po wyjściu z metody Run().

Aby stworzyć wątek typu Event-Driven:

  1. Wyprowadzamy nowa klasę dziedziczącą po klasie Thread.
  2. Nie przesłaniamy domyślnej metody Run(), a zadanie umieszczamy w metodzie OnStart().
  3. Kończymy wątek metodą Stop().

markac

Full-stack Web Developer

One thought to “Wielowątkowość – Event-Driven threads”

Komentarze są zamknięte.