Biorąc pod uwagę ten kod:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
Czy wszystkie 1000 wątków pojawią się prawie jednocześnie?
c#
.net
c#-4.0
parallel-processing
Jader Dias
źródło
źródło
Na komputerze z jednym rdzeniem ... Parallel.ForEach partycje (fragmenty) kolekcji, nad którymi pracuje, między wieloma wątkami, ale ta liczba jest obliczana na podstawie algorytmu, który bierze pod uwagę i wydaje się stale monitorować pracę wykonywaną przez wątków, które alokuje do ForEach. Więc jeśli część ciała ForEach wywołuje długo działające funkcje związane z IO / blokujące, które pozostawiałyby wątek czekający w pobliżu, algorytm odrodzi więcej wątków i ponownie podzieli kolekcję między nimi . Jeśli wątki kończą się szybko i nie blokują na przykład wątków we / wy, takich jak po prostu obliczanie niektórych liczb,algorytm zwiększy (lub faktycznie zmniejszy) liczbę wątków do punktu, w którym algorytm uzna za optymalny dla przepustowości (średni czas zakończenia każdej iteracji) .
Zasadniczo pula wątków za wszystkimi różnymi funkcjami biblioteki równoległej opracuje optymalną liczbę wątków do użycia. Liczba fizycznych rdzeni procesorów stanowi tylko część równania. NIE ma prostej zależności jeden do jednego między liczbą rdzeni a liczbą utworzonych wątków.
Dokumentacja dotycząca anulowania i obsługi synchronizacji wątków nie jest dla mnie zbyt pomocna. Miejmy nadzieję, że MS może dostarczyć lepsze przykłady w MSDN.
Nie zapominaj, że kod body musi być napisany tak, aby działał w wielu wątkach, wraz ze wszystkimi typowymi względami dotyczącymi bezpieczeństwa wątków, struktura nie wyodrębnia tego czynnika ... jeszcze.
źródło
Wypracowuje optymalną liczbę wątków na podstawie liczby procesorów / rdzeni. Nie wszystkie odrodzą się na raz.
źródło
Zobacz Does Parallel. For use one Task na iterację? na pomysł „modelu mentalnego” do wykorzystania. Jednak autor stwierdza, że „Pod koniec dnia należy pamiętać, że szczegóły implementacji mogą w każdej chwili ulec zmianie”.
źródło
Świetne pytanie. W twoim przykładzie poziom zrównoleglenia jest dość niski nawet w przypadku czterordzeniowego procesora, ale po pewnym czasie poziom zrównoleglenia może być dość wysoki.
Teraz spójrz, co się stanie, gdy zostanie dodana operacja oczekująca, aby zasymulować żądanie HTTP.
Nie wprowadziłem jeszcze żadnych zmian, a poziom współbieżności / równoległości gwałtownie podskoczył. Limit współbieżności można zwiększyć za pomocą
ParallelOptions.MaxDegreeOfParallelism
.Polecam ustawienie
ParallelOptions.MaxDegreeOfParallelism
. Niekoniecznie zwiększy to liczbę używanych wątków, ale zapewni, że uruchomisz tylko rozsądną liczbę wątków, co wydaje się być twoim problemem.Na koniec odpowiadając na pytanie: nie, nie wszystkie wątki zaczną się od razu. Użyj Parallel.Invoke, jeśli chcesz wywołać równolegle idealnie, np. Testowanie warunków wyścigu.
źródło