Najlepszy sposób na rozpoczęcie wątku jako członek klasy C++?
Zastanawiam się nad najlepszym sposobem na uruchomienie pthread, który jest członkiem klasy C++? Moje własne podejście jest odpowiedzią...
5 answers
Zwykle używam statycznej funkcji członka klasy i używam wskaźnika do klasy jako parametru void *. Ta funkcja może następnie albo wykonać przetwarzanie wątku, albo wywołać inną niestatyczną funkcję członka z referencją do klasy. Ta funkcja może wtedy odwoływać się do wszystkich członków klasy bez niewygodnej składni.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 18:27:15
Można to po prostu zrobić za pomocą biblioteki boost, jak to:
#include <boost/thread.hpp>
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
boost::thread* pThread = new boost::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
Uwagi:
- używa zwykłej funkcji członka klasy. Nie ma potrzeby dodawania dodatkowych, statycznych członków, które mylą interfejs klasy
- wystarczy dodać boost/thread.hpp w pliku źródłowym, w którym rozpoczynasz wątek. Jeśli dopiero zaczynasz z boostem, cała reszta tego dużego i zastraszającego pakietu może zostać zignorowana.
W C++11 możesz zrobić to samo, ale bez boost
// define class to model or control a particular kind of widget
class cWidget
{
public:
void Run();
}
// construct an instance of the widget modeller or controller
cWidget theWidget;
// start new thread by invoking method run on theWidget instance
std::thread * pThread = new std::thread(
&cWidget::Run, // pointer to member function to execute in thread
&theWidget); // pointer to instance of class
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-08 15:14:40
Musisz go bootstrap używając parametru void*:
class A { static void* StaticThreadProc(void *arg) { return reinterpret_cast<A*>(arg)->ThreadProc(); } void* ThreadProc(void) { // do stuff } }; ... pthread_t theThread; pthread_create(&theThread, NULL, &A::StaticThreadProc, this);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 19:04:29
Użyłem trzech z opisanych powyżej metod. Kiedy po raz pierwszy użyłem threadingu w c++ użyłem static member functions, następnie friend functionsi wreszcie BOOST libraries. Obecnie wolę BOOST. W ciągu ostatnich kilku lat stałem się wielkim BIGOTEM.
BOOST jest do C++ tak jak CPAN do Perla. :)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 20:28:55
Biblioteka boost zapewnia mechanizm kopiowania, który pomaga w przesyłaniu informacji o obiekcie do nowego wątku. W innym przykładzie boost:: bind zostanie skopiowane ze wskaźnikiem, który również jest po prostu skopiowany. Więc musisz zadbać o ważność obiektu, aby zapobiec zwisającemu wskaźnikowi. Jeśli zaimplementujesz operator () i zamiast tego dostarczysz Konstruktor kopiujący i przekażesz obiekt bezpośrednio, nie musisz się tym przejmować.
O wiele ładniejsze rozwiązanie, które zapobiega wielu "trouble": {]}#include <boost/thread.hpp>
class MyClass {
public:
MyClass(int i);
MyClass(const MyClass& myClass); // Copy-Constructor
void operator()() const; // entry point for the new thread
virtual void doSomething(); // Now you can use virtual functions
private:
int i; // and also fields very easily
};
MyClass clazz(1);
// Passing the object directly will create a copy internally
// Now you don't have to worry about the validity of the clazz object above
// after starting the other thread
// The operator() will be executed for the new thread.
boost::thread thread(clazz); // create the object on the stack
Drugi przykład boost tworzy obiekt thread na stercie, chociaż nie ma sensu tego robić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-12 17:37:35