malloc i free a wątki w C

0

jeżeli jeden wątek w C zaalokuje pamięć a drugi wątek ją potem zwolni mogą być jakieś problemy?

4

Ogólnie, to jest zdefiniowane zachowanie, o ile nie masz żadnych dodatkowych data races przy tym. Problemy mogą się pojawić, np. problemy wydajnościowe. Pytanie, co masz na myśli?

0

pomysł kolegi, ja chcę użyć stałego bufora do którego jeden wątek zapisuje a drugi odczytuje, a on proponuje dwukierunkową listę

11

Wątki maja wspólną stertę i osobne, "prywatne" stosy. Tak więc alokacja w jednym wątku i zwalanianie w innym nie jest problemem jako takim, w sensie możesz to zrobić, ale bez synchronizacji problemem mogą być potencjalne wyścigi czy use after free.

0

share_ptr unique_ptr
raczej to co napisałeś to nic "zdrożnego"

3

Wątków generalnie nie polecam używać, bo ludzie tego generalnie nie potrafią używać, tam po prostu łatwo o błąd. ;)
Ale jeśli one już tam są i pytasz o strukturę danych... lista potrafi się dobrze sprawdzać jako wielowątkowa kolejka, to jest często "typowa go-to struktura". Natomiast raczej nie ma problemów z alokowaniem z jednego i zwalnianiem z drugiego wątku, tak długo przynajmniej jak nie masz data races, double free i innych tego rodzaju problemów.

Argument przeciwko alokacji na wielu wątkach jest potencjalnie taki, że malloc może w zależności od implementacji brać globalny mutex, więc wszystko zastopuje jeśli akurat parę wątków zechce w danym momencie zaalokować. Małe embeddy tak często (citation needed, bo piszę z doświadczenia wyłącznie) działają, duże maszyny - już niekoniecznie.
Do poczytania:
https://stackoverflow.com/questions/10706466/how-does-malloc-work-in-a-multithreaded-environment
...ale obawiam, się, że bez profilera to generalnie możemy sobie dumać nad false sharingiem, cache miss i innymi przyjemnostkami.
A jeżeli to nie jest ważny wydajnościowo kod, to weźcie taką strukturę, żeby logikę dobrze/intuicyjnie oddawała...

1

ostatnio słyszałem o takim przypadku. Była za alokowana pamięć jakiś tam wątek sobie używał pewnego miejsca w pamięci. Ale za zwalnianie tego miejsca był odpowiedzialny inny wątek z timerem który dane takiej struktury dealokował. No i był gdzieś błąd i pamięć ciekła. Podsumowując, to zawsze niebezpieczeństwo. Ogólnie w tej książce link znajdziesz opisy problemów przy współdzieleniu pamięci miedzy watkami(są rozdziały o tym :)) Bo generalnie w wielowatkowości są zawsze akcje typu coś działa wolniej niż by mogło przez muteksy albo są zakleszczenia i ja sam unikam jak mogę dzielenia jakiś danych.

pomysł kolegi, ja chcę użyć stałego bufora do którego jeden wątek zapisuje a drugi odczytuje,

Zawsze jak czytam o tym pomyśle mam przed oczami producent-konsument.

0
revcorey napisał(a):

Była za alokowana pamięć jakiś tam wątek sobie używał pewnego miejsca w pamięci. Ale za zwalnianie tego miejsca był odpowiedzialny inny wątek z timerem który dane takiej struktury dealokował. No i był gdzieś błąd i pamięć ciekła.

właśnie takich informacji szukam, tyle ze na jutro to potrzebuję wiec książki przeczytać nie zdążę

1

@Miang: No widzisz. To już podałem ci problem. Pamieć może cieknąć. Tyle jest jedno ale, to zależy od logiki. W tym co przytoczyłem była ifologia i gdzieś był błąd objawiający się czasami. Generalnie odpowiedzcie sobie na pytanie co wy tam chcecie osiągnąć i jak skomplikowany problem chcecie rozwiązać. Czy jest sytuacja w której wątek który ma posprzątać może ignorować takową konieczność(jakiś warunek z if i continue). Co taki wątek ma robić w destruktorze? Jak logika tego sprzątającego wątku będzie jakaś skomplikowana to i rośnie niebzpieczeństwo wycieków itd.
znalazłem taki ciekawy temat na stack overflow
https://stackoverflow.com/questions/4167624/concurrent-linked-list

Linked lists are inherently sequential data structures. No matter what kind of machinery you use to implement it, the interface and expected behavior imply sequential logic.

2

To jedno z głównych zastosowań sterty: współdzielenie pamięci pomiędzy wątkami. Pamięć na stercie nie jest przypisana do stosu danego wątku, więc nie należy stricte do żadnego wątku. Oczywiście nowoczesne alokatory robią różne tricki, żeby alokacja/dealokacja z tego samego wątku była jak najbardziej szybka, bo to najważniejszy case (alokacja dużych ilości pamięci różnego rozmiaru)

0

""pomysł kolegi, ja chcę użyć stałego bufora do którego jeden wątek zapisuje a drugi odczytuje, ""
Zdaję sobie sprawę, że to może działać.
Natomiast bez mutexa teoria jest taka, że nie wolno Ci tego zrobić.

"jeżeli jeden wątek w C zaalokuje pamięć a drugi wątek ją potem zwolni mogą być jakieś problemy?""
Nie widzę problemu. Często przekazuje jakieś dane przez pointer tworząc wątasa które alokowałem i główny wątek już ich nie używa.
Uwalniam w wątku, który dostał wskaźnik.

1

Zasadniczo odradzałbym alokację pamięci w wątkach - może to powodować rywalizację wątków i spore spadki wydajności (przy dużej ilości wątków). Malloc w wersji thread safe jest blokujący.
Musisz też ustalić, który wątek jest właścicielem i to on powinien zwalniać zasoby.

Co do bufora vs. listy, to można połączyć obydwa pomysły i stworzyć stały bufor, który będzie działać jako memory pool dla listy. Wówczas faktycznie żadna alokacja/dealokacja nie będzie mieć miejsca, a funkcjonalnie będzie lista + w takiej formie dość łatwo będzie ją zrobić nieblokująco z dobrymi gwarancjami progresu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1