2009-08-27 17 views
6

W języku C podanie zmiennej w zakresie globalnym powoduje, że jest to zmienna globalna. Czy ta zmienna globalna jest współużytkowana wśród wątków, czy jest przydzielana dla wątku?C globalne statyczne - udostępniane między wątkami?

Aktualizacja: Jeśli są one współużytkowane przez wątki, w jaki prosty sposób można tworzyć globale w istniejącej bibliotece unikalnej dla wątku/niewspółużytkowanej?

Update2: Zasadniczo, potrzebuję użyć istniejącej biblioteki C z globalsami w sposób bezpieczny dla wątków.

+4

Deklarowanie zmiennej statycznej powoduje, że jest to zmienna zakresu pliku. Deklaracja, że ​​nie jest statyczna, czyni go globalnym. –

+0

Dziękuję za wyjaśnienie. – jameszhao00

+0

Z jakiego systemu operacyjnego korzystasz? Myślę, że może istnieć rozwiązanie specyficzne dla platformy dla Update2. –

Odpowiedz

16

Jest widoczny dla całego procesu, tj. dla wszystkich wątków. Oczywiście tak jest w praktyce. Teoretycznie nie można powiedzieć, ponieważ wątki nie mają nic wspólnego ze standardem C (przynajmniej do c99, który jest standardem, który obowiązywał, gdy zadawano to pytanie).

Jednak wszystkie biblioteki wątków, z których korzystałem, miałyby globale dostępne dla wszystkich wątków.


Aktualizacja 1:

Wiele bibliotek wątek (pthreads, za jeden) pozwoli Ci stworzyć dane gwintu specyficzne środki do funkcji tworzyć i wykorzystywać dane specyficzne dla wątku bez konieczności przeszedł przez tę funkcję.

Na przykład funkcja zwracania liczb pseudolosowych może chcieć, aby każdy wątek posiadał niezależny materiał siewny. Tak więc za każdym razem, gdy się go nazywa, albo tworzy lub przyłącza się do specyficznego dla wątku bloku, trzymającego to nasiono (używając jakiegoś klucza).

Umożliwia to zachowanie tych samych sygnatur, co te, które nie są gwintowane (ważne, jeśli na przykład są to funkcje ISO C), ponieważ inne rozwiązanie polega na dodaniu wskaźnika specyficznego dla wątku do samego wywołania funkcji.

Inną możliwością jest, aby mieć tablicę globalnych, z których każdy wątek dostaje jeden, takich jak:

int fDone[10]; 
int idx; 
: : : 
for (i = 0; i < 10; i++) { 
    idx = i; 
    startThread (function, i); 
    while (idx >= 0) 
     yield(); 
} 

void function() { 
    int myIdx = idx; 
    idx = -1; 
    while (1) { 
     : : : 
    } 
} 

Pozwoliłoby to funkcja gwint być poinformowani, która zmienna globalna w tablicy należy do niego .

Istnieją inne metody, bez wątpienia, ale brak znajomości środowiska docelowego, nie ma sensu je omawiać.


Aktualizacja 2:

najprostszy sposobem korzystania z biblioteki niż wątek bezpieczny w środowisku gwintowanych jest zapewnienie połączeń opakowania z ochrony mutex.

Załóżmy na przykład, że twoja biblioteka ma funkcję bezpieczną dla wątków (doThis()). Co zrobić, to dostarczyć opakowanie do niej:

void myDoThis (a, b) { 
    static mutex_t serialize; 
    mutex_claim (&serialize); 
    doThis (a, b); 
    mutex_release (&serialize); 
} 

Co się stanie, że istnieje tylko jeden wątek na raz będą mogli ubiegać się o mutex (a tym samym wywołać funkcję non-nić-safe). Inne będą zablokowane, dopóki nie powróci bieżący.

+0

Dzięki. Zaktualizowane pytanie nieco. – jameszhao00

+0

Przepraszamy. Zaktualizowany ponownie ... – jameszhao00

+0

W porządku, James, myślę, że nadążam teraz :-) – paxdiablo

1

Standard C/C++ nie obsługuje wątków. Więc wszystkie zmienne są współużytkowane przez wątki. Obsługa wątków zaimplementowana w bibliotece uruchomieniowej C/C++, która nie jest częścią standardu. Środowisko wykonawcze jest specyficzne dla każdej implementacji C/C++. Jeśli chcesz napisać przenośny kod w C++, możesz użyć boost interprocess library.

Aby zadeklarować zmienną lokalną wątku w Microsoft Visual Studio można użyć słowa kluczowego Microsoft: __declspec(thread).

1

Jak wspomniano o @Pax, zmienne statyczne są widoczne dla wszystkich wątków. Nie ma konstrukcji danych C++ powiązanej z konkretnym wątkiem.

Jednak w systemie Windows można użyć TlsAlloc API przeznaczyć indeksu dla danych specyficznych dla gwintów i umieścić ten indeks w zmiennej statycznej. Każdy wątek ma własny slot, do którego można uzyskać dostęp za pomocą tego indeksu oraz TlsGetValue i TlsSetValue. Więcej informacji można znaleźć na stronie MSDN pod numerem telefonu Using Thread Local Storage.

Aktualizacja: Nie ma sposobu, aby globale w istniejącej bibliotece były specyficzne dla wątku. Wszelkie rozwiązania wymagałyby modyfikacji kodu, aby mieć świadomość, że dane mają powinowactwo do wątku.

Powiązane problemy