2010-05-16 7 views
11

czytałem to: http://en.wikipedia.org/wiki/Thread_safetybezpieczeństwo Temat z sterty przydzielona pamięć

jest następująca funkcja wątku bezpieczny?

void foo(int y){ 
    int * x = new int[50]; 
    /*...do some stuff with the allocated memory...*/ 
    delete [] x; 
} 

W artykule napisano, że do zachowania wątków można używać tylko zmiennych ze stosu. Naprawdę? Czemu? Czy kolejne wywołania powyższej funkcji nie przydzielają pamięci w innym miejscu?

Edytuj: Ah. Wygląda na to, że błędnie zinterpretowali tę część artykułu:

Podprogram jest wklęsłego, a tym samym wątku bezpieczny, jeśli

  • jedynych używanych w nim zmiennych są ze stosu

(Wziąłem to w znaczeniu

Podprogram jest powtarzalny, a więc bezpieczny dla wątków, jeśli i tylko wtedy

  • jedyne zmienne wykorzystywane przez to ze stosu

, który według poniższych odpowiedzi, nie jest)

+9

Użyj 'delete []' dla tablic nie 'delete' –

+0

@Brian: Woops - thanks. Dodałem część tablicową po tym, jak już wypisałem tę funkcję, aby było jeszcze bardziej jasne, że dynamicznie przydzielam pamięć, ale zapomniałem dodać []. +1 :) – Cam

+1

Zdumiewające jest rozpowszechnianie użycia Wikipedii jako referencji do programowania pojęć :) – ch0kee

Odpowiedz

10

Jeśli kodowanie w środowisku, które obsługuje wielowątkowości, to można być całkiem pewny new jest bezpieczny dla wątków.

Mimo że pamięć znajduje się na stercie, wskaźnik do niej znajduje się na stosie. Tylko twój wątek ma wskaźnik do tej pamięci, więc nie ma ryzyka jednoczesnej modyfikacji - żaden inny wątek nie wie, gdzie pamięć ma go modyfikować.

Wystąpiłby problem z bezpieczeństwem wątków, gdybyś przekazał ten wskaźnik do innego wątku, który jednocześnie modyfikowałby tę pamięć w tym samym czasie co oryginalny (lub inny) wątek.

+0

Dzięki. Trudny wybór pomiędzy twoją odpowiedzią a Piotrem, ale twoja pomocna podpowiedź na końcu była trafna, podczas gdy jego dotyczyły wektorów :) – Cam

0

new i delete może lub może nie być bezpieczne dla wątków. Prawdopodobnie są, ale to zależy od implementacji. Zobacz: C++ new operator thread safety in linux and gcc 4

Aby być bezpiecznym w wątku, funkcja musi albo wykorzystywać zmienne stosu, albo synchronizować dostęp do innych zasobów z innymi wątkami. Dopóki oddzielne wywołania do nowych przydzielają inną przestrzeń na stercie, gdy są wywoływane z różnych wątków, powinieneś być w porządku.

2

Nie mówi, że można używać tylko zmiennych stosu, mówi, że użycie zmiennych sterty "sugeruje potrzebę dokładnego sprawdzenia, czy jest to niebezpieczne".

new i delete są zwykle zaimplementowane w sposób bezpieczny dla wątków (nie jest pewne, że standard to gwarantuje), więc powyższy kod prawdopodobnie będzie w porządku.

Plus zwyczajowe zalecenia użyciu std::vector zamiast ręcznego przydzielania tablicę, ale zakładam, że tylko pod warunkiem, że jako przykład :)

+1

Przypominam sobie, że działam w środowisku, w którym nie było. Teraz * to * było włochate. – Joshua

+1

To szczęście, że możesz je zastąpić :) –