Funkcje wątkowe o wielu parametrach
Na podstawie moich nowych Callback’ów obmyśliłem sobie na szybko mini system do tworzenia wątków o dowolnej ilości parametrów. Używam biblioteki POSIX Thread (pthread) i jest tam dosyć osobliwe – bo znane – ograniczenie. Można – a nawet trzeba – tam podać tylko jeden argument, ściśle określonego typu – void*. Ja oczywiście postanowiłem temu zapobiec.
Z czego korzystam
Oprócz biblioteki pthread używam jeszcze swojej klasy Callback. Dla przypomnienia (tudzież podania właściwej wersji) – pliki przekopiowane DO, a następnie wydarte Z mojego silnika, czyli dosyć użyteczna wersja (wyprana :):
Idea
Moim nowym pomysłem jest możliwość zrobienia czegoś takiego:
//nasza funkcja void my_thread( int a, int b, int c ); //'wskaznik' do naszej funkcji Callback func( 3, this, &my_thread, 1, 2, 3 ); //stworzenie watka z funkcji, ktora przyjmuje 3 (>1) parametry threads->createThread( func );
Rozwiązanie
Co się dzieje w środku? Prosta procedurka, po okazaniu kodu wszystko powinno stać się jasne:
//pokaze tylko niezbedny kod int Threads::createThread( Callback& func ) { //... //tutaj jakies tam ewentualne wewnetrzne sprawy //... pthread_t thread; //jako parametr podajemy wskaznik do obiektu typu callback pthread_create( &thread, NULL, &TemporaryThread, (void*)&func ); //zwracamy klientowi id return thread.id; } //tymczasowy thread, ktory podajemy funkcji pthread_create() void* TemporaryThread( void* callback_ptr ) { //uzywamy podanego nam wskaznika i ew. zwracamy co trzeba. //Jezeli funkcja nic nie zwraca, zwrocone bedzie NULL return (void*) ((Callback*) callback_ptr)->callInt(); }
Wyjaśnienie
Nasz TemporaryThread() zachowuje się jak wrapper na właściwą funkcję, a że jest on już wątkiem, to wszystkie jego instrukcje – także wywołania innych funkcji – będą działały w tym samym wątku. Nasza klasa do wątków nie wywołuje bezpośrednio przez nas podanego ale właśnie tego wrappera. Takie rozwiązanie pozwala nam na znacznie bardziej kompleksowe używanie wątków :)
Marzec 26th, 2008 at 12:05
Znana i lubiana sztuczka :) Działa też w Windows, gdzie wątki tworzy się analogicznie. Można to jeszcze usprawnić, czyniąc TemporaryThread prywatną metodą statyczną klasy Thread – wtedy żadne bebechy implementacji na pewno nie wyciekną na zewnątrz.