Pthread na Windows

Ten post ma na celu przyznanie się do błędu 😉

Otóż niedawno napisałem, że obsługa pthread pod Win32 ma jakieś problemy i wywala błędy. Jest to oczywiście be-zdura! Tzn, nie wiem jak to dokładnie jest bo nie analizowałem całej biblioteki, ale wiem teraz na pewno, że błąd, który pojawiał się u mnie był spowodowany… no właśnie… czym?

Błąd dość ciekawy i początkowo patrząc na niego nawet nie zdawałem sobie sprawy z tego, że to akurat ten kawałek kodu jest winny 😉 Kod wyglądał jakoś tak:

SThread st = { this, arg };
pthread_create( &tid, NULL, RunThreadFunc, &st );

No i fajnie, gdzie tu problem?

Wprawni programiści zapewne już wiedzą co się święci. Możliwe, też że mnie wprawni również to widzą 😛 W gruncie rzeczy nie trzeba mieć nawet wiele wspólnego z kodem…

Chodzi oczywiście o to, że st (którego adres przekazuję jako parametr do nowego wątku) jest niszczone po zakończeniu funkcji, w której powyższy kod jest zawarty. Jednak funkcja pthread_create tworzy nowy wątek, który może zacząć wykonywanie w tym samym czasie, ale najczęściej pewnie tak się nie stanie. Stąd od razu wiadomo dlaczego błąd czasem się pojawiał, a czasem nie. Jeśli nowy wątek zaczął się wykonywać jeszcze przed zakończeniem funkcji, w której został utworzony to wtedy nic się nie działo. Częściej jednak zdarzało się, że zaczynał się później i próbował odczytać adres st, który był już zwolniony.

Dlatego też proszę o wybaczenie urażonych moim postem o ułomności pthreads pod Win32 😉 

Ciekawostką jest, że w Ubuntu NIGDY mi się nie zdarzyło, aby powstał ten błąd więc widocznie potrafi on znacznie szybciej uruchomić nowo utworzony wątek ^^

2 komentarze do “Pthread na Windows

  1. Heh, ciekawy błąd. Brawo że go znalazłeś. Intryguje mnie teraz, czy dokumentacja funkcji pthread_create mówi, że ta struktura musi istnieć przez czas działania wątku, a nie tylko do wywołania tej funkcji. Jeśli nie określa tego jasno, to wtedy jest to ewidentny błąd twórców biblioteki (błąd w dokumentacji). W końcu ta funkcja mogłaby przecież równie dobrze kopiować sobie tą strukturę do swojej jakiejś wewnętrznej pamięci. Struktury przekazywane do funkcji WinAPI zawsze muszą istnieć tylko na czas wywołania funkcji.

  2. @Reg; sprawa nie jest prosta dla programistów biblioteki bo ostatni parametr w pthread_create jest wskaźnikiem na argumenty dla funkcji głównej nowego wątku. Stąd wynika, że nie pthread_create() nie może zrobić kopii tego obiektu ponieważ nie zna jego rozmiaru. Wartość wskaźnika była przekazywana poprawnie. Problem leżał w tym, że wątek, który startował z dostawał adres i chciał zczytać z pamięci miejsce, które zostało zwolnione bo funkcja w której argument był stworzony się skonczyła.

    Moim zdaniem nie ma co winić programistów biblioteki tylko muszę się przyznać, że dałem ciała podczas przemyśliwania 😉

Dodaj odpowiedź do moriturius Anuluj pisanie odpowiedzi