Zakładając, że środowisko wykonawcze C # używa równoważnych natywnych wywołań systemowych do odrodzenia innego wątku (i dlatego jest naprawdę równoległe; nie dzieje się tak w przypadku wszystkiego, jak niesławna Globalna Blokada Interpretera CPython ), zależałoby to wyłącznie od harmonogramu procesów / zadań systemu operacyjnego . Na ogół jednak, kod jest naprawdę wątku bezpieczne, jeśli założymy, że t1i t2są wykonywane w różnych momentach w dowolnej kolejności (np Jest to możliwe t2starty wcześniejt1 w niektórych modelach).
Przełom
2
Nie wiedziałem, że były procesory Pentium i5. Może miałeś na myśli Core i5? Wybredna. Wiem: D
JosephGarrone
Odpowiedzi:
18
Nie można zagwarantować w .Net, że dwa Threads działają na dwóch oddzielnych rdzeniach. W rzeczywistości nie można również zagwarantować, że Threadbędzie działał tylko na jednym rdzeniu (!) .
Wynika to z faktu, że zarządzane wątki nie są takie same jak wątki systemu operacyjnego - jeden zarządzany wątek może używać wielu wątków systemu operacyjnego do obsługi tego. W języku C # zawsze masz do czynienia tylko bezpośrednio z zarządzanymi Threads (przynajmniej bez uciekania się do p / invoke w celu wywołania funkcji wątkowania WinAPI, czego nigdy nie powinieneś robić) .
Jednak harmonogramy wątków .Net i Windows są bardzo dobre w tym, co robią - nie uruchomiłyby dwóch wątków na jednym rdzeniu, podczas gdy drugi rdzeń jest całkowicie bezczynny. Ogólnie rzecz biorąc, nie musisz się tym martwić.
W praktyce, .net Threads są wątki OS. Ale nie dlatego nie ma gwarancji, że pojedynczy wątek zawsze będzie wykonywany na tym samym rdzeniu.
sick
2
@svick: W praktyce na x86 to prawda. Jednak standard wyraźnie stwierdza, że nie można polegać na tym zachowaniu, więc może się to zmienić w przyszłości. W rzeczywistości nie jest to prawdą w innych wersjach .Net CLR, takich jak XBox 360.
BlueRaja - Danny Pflughoeft
@BlueRaja - pytanie dotyczy konkretnej wersji CLR, o której mówimy. Możesz zagwarantować, że coś będzie istniało na dwóch oddzielnych rdzeniach, używając wątków asynchronicznych, ponieważ oznaczałoby to, że wystąpiłyby asynchronicznie względem siebie. Bieżący przykładowy kod jest połączeniem synchronicznym technicznie. Oczywiście system operacyjny decyduje, jakie rdzenie zostaną użyte.
Ramhound,
@Ramhound „Możesz zagwarantować, że coś będzie istniało na dwóch oddzielnych rdzeniach za pomocą wątków asynchronicznych” - to nieprawda. Słowo asynckluczowe (o którym zakładam, że mówisz, ponieważ „wątki asynchroniczne” jest zbędne) to po prostu cukier syntaktyczny do używania BackgroundWorkerwątku, który jest jak każdy inny wątek .Net - nie możesz zagwarantować, że będzie działał na osobny rdzeń czy nie.
BlueRaja - Danny Pflughoeft
@BlueRaja - Gdyby uruchomiono dwa wątki asynchroniczne, oba działałyby w tym samym czasie, pod warunkiem, że będą 2 rdzenie procesora. Gdyby był tylko jeden, system operacyjny zaplanowałby, kiedy każdy wątek otrzyma priorytet i uruchomi się, a wtedy wystąpi typowa sytuacja z thrashowaniem w jednym wątku. W ten sposób nauczono mnie, jak procesor obsługuje wiele wątków.
Ramhound,
15
Nie, system operacyjny i procesor decydują o tym, co uruchomić i kiedy. w prostym przykładzie, który pokazałeś, z wyłączeniem innych zadań, tak, najprawdopodobniej działałyby one równolegle na osobnych rdzeniach, ale rzadko istnieje gwarancja, że tak będzie.
Koligacji wątków można użyć do próby przejęcia kontroli nad przydzieleniem rdzenia do danego wątku.
Weź również pod uwagę priorytety planowania, aby układać talię pod względem tego, które wątki powinny być całkowicie równoległe i które mogą czekać.
Chcę również dodać, że dzięki technologiom wirtualizacji istnieje inna warstwa między twoim programem a sprzętem. To, co system operacyjny przedstawia aplikacji, może nie być fizycznie dokładne.
Keltari
1
Są to funkcje WinAPI dla wątków systemu operacyjnego, a nie dla wątków zarządzanych. Nigdy nie powinny być wywoływane z C #, ponieważ mogą poważnie zakłócać harmonogram wątków .Net
t1
it2
są wykonywane w różnych momentach w dowolnej kolejności (np Jest to możliwet2
starty wcześniejt1
w niektórych modelach).Odpowiedzi:
Nie można zagwarantować w .Net, że dwa
Thread
s działają na dwóch oddzielnych rdzeniach. W rzeczywistości nie można również zagwarantować, żeThread
będzie działał tylko na jednym rdzeniu (!) .Wynika to z faktu, że zarządzane wątki nie są takie same jak wątki systemu operacyjnego - jeden zarządzany wątek może używać wielu wątków systemu operacyjnego do obsługi tego. W języku C # zawsze masz do czynienia tylko bezpośrednio z zarządzanymi
Thread
s (przynajmniej bez uciekania się do p / invoke w celu wywołania funkcji wątkowania WinAPI, czego nigdy nie powinieneś robić) .Jednak harmonogramy wątków .Net i Windows są bardzo dobre w tym, co robią - nie uruchomiłyby dwóch wątków na jednym rdzeniu, podczas gdy drugi rdzeń jest całkowicie bezczynny. Ogólnie rzecz biorąc, nie musisz się tym martwić.
źródło
Thread
s są wątki OS. Ale nie dlatego nie ma gwarancji, że pojedynczy wątek zawsze będzie wykonywany na tym samym rdzeniu.async
kluczowe (o którym zakładam, że mówisz, ponieważ „wątki asynchroniczne” jest zbędne) to po prostu cukier syntaktyczny do używaniaBackgroundWorker
wątku, który jest jak każdy inny wątek .Net - nie możesz zagwarantować, że będzie działał na osobny rdzeń czy nie.Nie, system operacyjny i procesor decydują o tym, co uruchomić i kiedy. w prostym przykładzie, który pokazałeś, z wyłączeniem innych zadań, tak, najprawdopodobniej działałyby one równolegle na osobnych rdzeniach, ale rzadko istnieje gwarancja, że tak będzie.
Koligacji wątków można użyć do próby przejęcia kontroli nad przydzieleniem rdzenia do danego wątku.
Weź również pod uwagę priorytety planowania, aby układać talię pod względem tego, które wątki powinny być całkowicie równoległe i które mogą czekać.
źródło