malloc i free a wątki w C

malloc i free a wątki w C
Miang
  • Rejestracja:około 7 lat
  • Ostatnio:3 minuty
  • Postów:1674
0

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


dzisiaj programiści uwielbiają przepisywać kod z jednego języka do drugiego, tylko po to by z projektem nadal stać w miejscu ale na nowej technologii
enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:12 dni
  • Postów:1027
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?

Miang
  • Rejestracja:około 7 lat
  • Ostatnio:3 minuty
  • Postów:1674
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ę


dzisiaj programiści uwielbiają przepisywać kod z jednego języka do drugiego, tylko po to by z projektem nadal stać w miejscu ale na nowej technologii
BG
Jeśli dane są produkowane i konsumowane w tym samym tempie, to rozważcie jakiś bufor cykliczny (możecie go nawet zrobić w pamięci współdzielonej i wtedy producent i konsument nie muszą być tym samym procesem)
Miang
@Bartłomiej Golenko: no właśnie szukam argumentów za tym rozwiązaniem a przeciwko innemu ;) może nie do końca konsumowane w tym samym tempie ale jak się kolejka zapcha to moim zdaniem problem będzie poważniejszy i tak czy inaczej musimy takie sytuacje wyłapać
several
  • Rejestracja:ponad 15 lat
  • Ostatnio:około 8 godzin
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.


edytowany 1x, ostatnio: several
Azarien
ale co "szkoda"? dostałeś odpowiedź twierdzącą - można. ale trzeba uważać na typowo wielowątkowe problemy: nie będzie łatwo zrobić to dobrze.
XK
  • Rejestracja:ponad 16 lat
  • Ostatnio:około rok
0

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

edytowany 1x, ostatnio: xkpit
pylaochos
poza tym, że mowa o C to po co miały być tu smart ptry?
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 3 lata
  • Postów:1493
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...

Miang
no tak ale alokacja niedużej struktury to raczej szybko idzie chyba
AL
@Miang: nie wiem, zmierz ;) zasadniczo: problemem jest performance, czy co Ci się nie podoba w tych alokacjach?
Miang
nie podoba mi się pomysł z listą , wolę bufor bo widzę przy tym mniej problemów ;)
RE
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 4 godziny
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.


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile
edytowany 1x, ostatnio: revcorey
Zobacz pozostałe 3 komentarze
RE
@Miang: tak książka to taki trochę klasyk :)
Miang
a swoją drogą pomysł zmiany tego co kiepsko działa na wątek z nadzieją że zadziała lepiej mnie też nie zachwyca bo to nie mój pomysł
RE
raczej chodzi mi o over-engenering. Po prostu człowiek chciałby czasami zrobić taki ciekawy kod oparty o jakieś wątki, variadic template, patterny itd. A na końcu sie okazuje że to fakt state of art ale po co jak wystarcza znacznie prostsze konstrukcje? Taka inżynierska chętka chyba każdy kiedyś tak miał.
YA
@Miang: pomysł zmiany tego co kiepsko działa na wątek z nadzieją że zadziała lepiej mnie też nie zachwyca a jaki jest oryginalny problem?
Miang
@yarel problem jest w komunikacji ze sprzętem ten watek ma za to tylko odpowiadać a inne wysyłać do kolejki polecenia
Miang
  • Rejestracja:około 7 lat
  • Ostatnio:3 minuty
  • Postów:1674
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ążę


dzisiaj programiści uwielbiają przepisywać kod z jednego języka do drugiego, tylko po to by z projektem nadal stać w miejscu ale na nowej technologii
RE
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 4 godziny
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.


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile
edytowany 1x, ostatnio: revcorey
Zobacz pozostałe 2 komentarze
RE
moje zdanie, użyjcie prostszej struktury. Chyba że macie jakieś wymagania które wymagają listy. Czyli znowu wracamy do wymagań i jaki interfejs jest wam potrzebny.
Miang
właśnie nie chcę używać listy a kolega ma taki genialny pomysł i chce mnie uczyć dzieci robić....eee tzn. listę pisać
AL
@Miang: bo (dobrze zrobiona, wiadomo) lista jest teoretycznie najwydajniejsza jako wielowątkowa kolejka. Także to nie jest tak, że gość zabiera się do tematu z gruntu źle. Pytanie: macie w tym C jakąś listę/zestaw kontenerów już gotowych czy rzeźbicie to ręcznie „bo to C więc po co robić utilsy, napisze się ad hoc” :p ?
Miang
miałabym robić ręcznie i tak jak mówię gostek chce uczyć ojca dzieci robić czyli mi pokazać jak sie robi listę (jakbym nie wiedziała)
RE
@Miang: w tej książce którą poleciłem w jednym rozdziale jest pełna analiza listy jako miejsca komunikacji między wątkami. Pokazane zalety i wady róznych implementacji :) przeczytaj jeden rozdział, zastanów się mając na uwadze wasze wymagania.
SL
  • Rejestracja:około 7 lat
  • Ostatnio:około 2 godziny
  • Postów:890
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)

edytowany 2x, ostatnio: slsy
KS
  • Rejestracja:prawie 4 lata
  • Ostatnio:około 4 godziny
  • Postów:608
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.

Miang
no wiadomo że mutex przecież przy dodawaniu do listy też musiałby być mutex. 'wątasa' dobre ;)
Azarien
no „problemy” z wątkami to zawsze mogą być ;)
TR
  • Rejestracja:około 16 lat
  • Ostatnio:5 miesięcy
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.

Miang
jakby o przeciążeniu operatora new czytała ;)
TR
Przeciążanie new to tylko udogodnienie (zresztą w C tego nie ma). Możesz napisać po prostu allocator, który będzie miał funkcje typu alloc/dealloc i one będą się zajmować odpowiednim przydzielaniem pamięci ze wspomnianego bufora. Niemniej taka implementacja często bywa dużo wydajniejsza, ale to trzeba wszystko pomierzyć.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)