Stack elérése több szálról

Fórumok

Lehet abból probléma, ha több szál írja vagy olvassa valamelyik szál stackjét?

Lefoglalok memóriát a stacken C99-es variable-length array létrehozásával.
uint8_t data[N];

Ha több szálról használom az adott területet, akkor lehetséges, hogy kockázatosabb ez, mint ha a heapen foglalnám le a memóriát?
uint8_t *data = new uint8_t[N];

Csak azért merült fel a kérdés, mert előbbire a valgrind hibákat dobál...

Hozzászólások

Ha szinkronizálod a pointer beállítását és a felszabadítás után nem éred el a területet, akkor nem okoz problémát. De valóban nem tűnik nekem szép megoldásnak. Az oprendszernek lehet, hogy joga lenne tiltani a különböző szálaknak egymás stackjeinek az elérését.

Átírni malloc/free-re nem lehet olyan óriási munka.

ne tedd! erre a heap valo :-)

--
NetBSD - Simplicity is prerequisite for reliability

Ha az automatic storage duration ("stack") változók elérése versenymentes (tehát vagy szinkronizált, vagy nincs osztozkodás), és figyelsz arra, hogy a szálak élettartama a részhalmaza legyen a változó(k) élettartamának, akkor nem lesz gond. Egy példa.

(Bitfield-eknél az osztozkodás nem biztos, hogy ránézésre nyilvánvaló.)

Tobb problema:

1) A C99-ben nincsen new, malloc() van.
2) Amit te ugy hiszel, h a stacken van, lehet hogy a fordito regiszterbe pakolja (ld. mmx, sseN, avx), ezert tessek a volatile kulcsszot alkalmazni.

Ahogy irtak masok, a stacket az OS, CPU vagy maga az architektura kezelheti fura modon, erosen ellenjavallott a hasznalata.

A fordító semmit nem rak regiszterbe, aminek a címét átadod bármilyen függvénynek. Merthogy ugye a regiszterben levő változónak nincs címe...

Amúgy az eredeti felvetésre: a stack ilyen módon való abuzálásának egy nagy korlátja van: nem lehet korrektül megírni, csak ha a tulajdonos szál egy lockon alszik garantáltan, amíg a másik szál "matat" a változóin. Ellenkező esetben előfordulhat, hogy a tulajdonos szál exitál, és azonnali hatállyal invalidálódik a stackje. Ennek a "lockon várakozós" verziónak meg kb. semmilyen praktikus haszna nincs.

Szóval az egész felvetést értelmetlennek tartom.

A volatile-nak specifikáció szerint semmi köze sincs a szálakhoz (jóllehet tíz éve még keringtek ezzel ellentétes legendák). Két link a SUSv4-ből (az első (a specifikáció) normatív, a második (az indoklás) informatív) -- Memory Synchronization:

  1. http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html…
  2. http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html…

Egy elemzés a volatile-ról Hans Boehm-től.

Az ISO C11 szintén nem hozott létre kapcsolatot a volatile és a szálak között. A C11 rationale-t egyelőre nem sikerült megtalálnom, de utánanézek.

Kiegészítés a C11-hez: zárolás nélküli eléréshez az

_Atomic

type specifier-t és az

<stdatomic.h>

header-t hozták be, nem a volatile-nak varrták a nyakába. Ettől függetlenül vannak platformok, ahol a volatile (nem hordozhatóan) elégséges.

Úgy nézem azért vacakolhatott a valgrind, mert 2.3MB allokációnál akkorát változott a stack pointer, hogy azt stackváltásnak értelmezte.

Ez azért is fontos, mert miután visszaállítottam (szerintem) egyszálúra a programot, utána is ugyanezt a hibát adta.

Egyaltalan nem kockazatosabb, tokeletesen ugyanaz mintha heapen lenne. Arra termeszetesen figyelni kell, hogy a stack vegig ervenyes maradjon, de ebben semmi meglepo nincs, az ervenyessegre heapen ugyanugy figyelni kell.

(Elofordulhat hogy bizonyos rendszerekben a tul nagy stack foglalas problemakhoz vezet, de ha altalanos gepekrol beszelunk akkor ez nem szokott jelentkezni. Ahol pedig jelentkezik, ott altalaban masra is figyelni kell, nem csak erre...)
--
cythoon