Jestem dość dobrym programistą, mój szef jest również dość dobrym programistą. Chociaż wydaje się nie doceniać niektórych zadań, takich jak wielowątkowość i tego, jak trudne może być (uważam, że bardzo trudno jest zrobić coś więcej niż uruchomienie kilku wątków, czekanie na zakończenie wszystkich, a następnie zwracanie wyników).
W momencie, gdy zaczynasz martwić się impasami i warunkami wyścigu, jest mi bardzo trudno, ale wydaje się, że szef nie docenia tego - nie sądzę, żeby kiedykolwiek się z tym spotkał. Wystarczy uderzyć w niego blokadą, to prawie postawa.
Jak więc mogę go przedstawić lub wyjaśnić, dlaczego nie docenia złożoności współbieżności, równoległości i wielowątkowości? A może się mylę?
Edycja: Trochę o tym, co zrobił - przeglądaj listę, dla każdego elementu na tej liście utwórz wątek, który wykonuje polecenie aktualizacji bazy danych na podstawie informacji w tym elemencie. Nie jestem pewien, w jaki sposób kontrolował liczbę wątków wykonanych jednocześnie, chyba dodałby je do kolejki, gdyby było ich zbyt wiele (nie użyłby semafora).
źródło
Odpowiedzi:
Jeśli możesz liczyć na jakiekolwiek doświadczenie matematyczne, zilustruj, w jaki sposób normalny przepływ wykonywania, który jest zasadniczo deterministyczny, staje się nie tylko niedeterministyczny z kilkoma wątkami, ale wykładniczo złożony, ponieważ musisz upewnić się, że każde możliwe przeplatanie instrukcji maszynowych nadal będzie słuszne. Prostym przykładem zagubionej aktualizacji lub niepoprawnego odczytu jest często przyciągający wzrok.
„Uderz w to” jest trywialnym rozwiązaniem ... rozwiązuje wszystkie problemy, jeśli nie martwisz się wydajnością. Spróbuj zilustrować, jaki byłby hit wydajności, gdyby na przykład Amazon musiał zamknąć całe wschodnie wybrzeże, ilekroć ktoś w Atlancie zamówi jedną książkę!
źródło
Wielowątkowość jest prosta. Kodowanie aplikacji do wielowątkowości jest bardzo, bardzo łatwe.
Istnieje prosta sztuczka polegająca na użyciu dobrze zaprojektowanej kolejki komunikatów ( nie rozwijaj własnej) do przesyłania danych między wątkami.
Najtrudniejszą częścią jest próba magicznej aktualizacji wielu wątków przez wspólny obiekt. Wtedy staje się podatny na błędy, ponieważ ludzie nie zwracają uwagi na obecne warunki wyścigowe.
Wielu ludzi nie używa kolejek wiadomości i próbuje aktualizować współdzielone obiekty i stwarzać problemy dla siebie.
Trudne staje się zaprojektowanie algorytmu, który działa dobrze podczas przesyłania danych między kilkoma kolejkami. To jest trudne. Ale mechanika współistniejących wątków (poprzez wspólne kolejki) jest łatwa.
Należy również pamiętać, że wątki współużytkują zasoby we / wy. Program związany z operacjami we / wy (tj. Połączenia sieciowe, operacje na plikach lub operacje na bazach danych) prawdopodobnie nie będzie działał szybciej z dużą liczbą wątków.
Jeśli chcesz zilustrować problem aktualizacji obiektu współdzielonego, to proste. Usiądź naprzeciwko stołu z bukietem kart papierowych. Zapisz prosty zestaw obliczeń - 4 lub 6 prostych wzorów - z dużą ilością miejsca na stronie.
Oto gra. Każdy z was czyta formułę, pisze odpowiedź i odkłada kartę z odpowiedzią.
Każdy z was wykona połowę pracy, prawda? Skończyłeś w połowie czasu, prawda?
Jeśli twój szef nie myśli dużo i po prostu zaczyna, skończysz w jakiś sposób na konflikcie i obaj piszecie odpowiedzi na tę samą formułę. To nie zadziałało, ponieważ między wami czytacie przed napisaniem. Nic nie stoi na przeszkodzie, abyś czytał tę samą formułę i nadpisywał odpowiedzi.
Istnieje wiele sposobów tworzenia warunków wyścigu przy użyciu źle lub niezablokowanych zasobów.
Jeśli chcesz uniknąć wszystkich konfliktów, możesz pociąć papier na stos formuł. Zdejmujesz jedną z kolejki, zapisujesz odpowiedź i publikujesz odpowiedzi. Brak konfliktów, ponieważ oboje czytacie z kolejki komunikatów tylko do odczytu.
źródło
Programowanie wielowątkowe jest prawdopodobnie najtrudniejszym rozwiązaniem dla współbieżności. Zasadniczo jest to dość niska abstrakcja tego, co faktycznie robi maszyna.
Istnieje wiele podejść, takich jak model aktora lub pamięć transakcyjna (programowa) , które są znacznie łatwiejsze. Lub praca z niezmiennymi strukturami danych (takimi jak listy i drzewa).
Zasadniczo odpowiednie rozdzielenie problemów ułatwia wielowątkowość. Coś, o czym często się zapomina, gdy ludzie spawnują 20 wątków, wszystkie próbują przetworzyć ten sam bufor. Używaj reaktorów tam, gdzie potrzebujesz synchronizacji i ogólnie przesyłaj dane między różnymi pracownikami za pomocą kolejek komunikatów.
Jeśli masz blokadę w logice aplikacji, zrobiłeś coś złego.
Tak, technicznie rzecz biorąc, wielowątkowość jest trudna.
„Slap a lock on it” to właściwie najmniej skalowalne rozwiązanie problemów z współbieżnością, i w rzeczywistości pokonuje cały cel wielowątkowości. Powoduje to przywrócenie problemu z powrotem do modelu współbieżnego wykonywania. Im częściej to robisz, tym bardziej prawdopodobne jest, że w danym momencie działa tylko jeden wątek (lub 0 w impasie). Pokonuje cały cel.
To tak, jakby powiedzieć: „Rozwiązanie problemów trzeciego świata jest łatwe. Wystarczy rzucić na niego bombę”. Tylko dlatego, że istnieje trywialne rozwiązanie, nie czyni to problemu trywialnym, ponieważ zależy Ci na jakości wyniku.
Ale w praktyce rozwiązywanie tych problemów jest tak samo trudne jak wszelkie inne problemy programistyczne i najlepiej wykonywać je przy użyciu odpowiednich abstrakcji. Co w rzeczywistości jest dość łatwe.
źródło
Myślę, że pytanie to nie ma technicznego charakteru - IMO to kwestia zaufania. Często jesteśmy proszeni o odtwarzanie skomplikowanych aplikacji, takich jak - och, nie wiem - na przykład Facebook. Doszedłem do wniosku, że jeśli musisz wyjaśnić złożoność zadania niewtajemniczonemu / kierownictwu - w Danii coś jest zepsute.
Nawet jeśli inni programiści ninja mogliby wykonać to zadanie w 5 minut, twoje szacunki oparte są na twoich osobistych zdolnościach. Twój rozmówca powinien albo nauczyć się ufać twojej opinii w tej sprawie, albo zatrudnić kogoś, kogo słowo jest w stanie zaakceptować.
Wyzwanie nie polega na przekazywaniu implikacji technicznych, które ludzie albo ignorują, albo nie są w stanie zrozumieć podczas rozmowy, ale na ustanawianiu relacji wzajemnego szacunku.
źródło
Jednym prostym eksperymentem myślowym mającym na celu zrozumienie impasu jest problem „ filozofa ”. Jednym z przykładów, których używam do opisania, jak złe mogą być warunki wyścigowe, jest sytuacja Therac 25 .
„Po prostu uderzanie zamkiem” to mentalność kogoś, kto nie napotkał trudnych błędów w wielowątkowości. I możliwe, że myśli, że przeceniasz powagę sytuacji (ja nie - możliwe jest wysadzenie rzeczy w powietrze lub zabicie ludzi z błędami warunków wyścigowych, zwłaszcza z wbudowanym oprogramowaniem, które kończy się w samochodach).
źródło
Współbieżne aplikacje nie są deterministyczne. Przy wyjątkowo małej ilości całego kodu, który programista uznał za podatny na atak, nie kontrolujesz, kiedy część wątku / procesu zostanie wykonana w stosunku do dowolnej części innego wątku. Testowanie jest trudniejsze, trwa dłużej i jest mało prawdopodobne, aby znaleźć wszystkie defekty związane z współbieżnością. Wad, jeśli zostaną wykryte, są często subtelne, nie można ich konsekwentnie odtwarzać, dlatego ich naprawa jest trudna.
Dlatego jedyną poprawną aplikacją współbieżną jest taka, która jest poprawna, co nie jest często praktykowane w tworzeniu oprogramowania. W rezultacie odpowiedź S.Lota jest najlepszą ogólną radą, ponieważ przekazywanie wiadomości jest stosunkowo łatwe do udowodnienia.
źródło
Krótka odpowiedź w dwóch słowach: NIEDETERMINIZM OBSERWACYJNY
Długa odpowiedź: zależy od tego, jakiego podejścia do programowania współbieżnego używasz, biorąc pod uwagę problem. W książce Koncepcje, techniki i modele programowania komputerowego autorzy jasno wyjaśniają cztery główne praktyczne podejścia do pisania współbieżnych programów:
Teraz najłatwiejszym z tych czterech podejść oprócz oczywistego programowania sekwencyjnego jest deklaratywna współbieżność , ponieważ programy napisane przy użyciu tego podejścia nie mają zauważalnego niedeterminizmu . Innymi słowy, nie ma warunków rasowych , ponieważ warunki rasowe są jedynie obserwowalnym zachowaniem niedeterministycznym.
Ale brak zauważalnego niedeterminizmu oznacza, że istnieją pewne problemy , których nie możemy rozwiązać za pomocą deklaratywnej współbieżności. Oto miejsce, w które wchodzą dwie ostatnie niełatwe podejścia. Nie tak łatwa część jest konsekwencją zauważalnego niedeterminizmu. Teraz oba są objęte stanowym współbieżnym modelem i są również równoważne pod względem ekspresji. Ale ze względu na stale rosnącą liczbę rdzeni na procesor, wydaje się, że branża ostatnio zainteresowała się większą współbieżnością przekazywania komunikatów, co można zaobserwować we wzroście bibliotek przekazywania komunikatów (np. Akka dla JVM) lub języków programowania (np. Erlang ) .
Wspomniana wcześniej biblioteka Akka, poparta teoretycznym modelem aktora, upraszcza budowanie współbieżnych aplikacji, ponieważ nie musisz już zajmować się zamkami, monitorami ani transakcjami. Z drugiej strony wymaga innego podejścia do projektowania rozwiązania, tj. Myślenia w sposób hierarchiczny, złożony z aktorów. Można powiedzieć, że wymaga to zupełnie odmiennego sposobu myślenia, co w końcu może być jeszcze trudniejsze niż korzystanie ze współbieżności współdzielonej w stanie zwykłym.
Współbieżne programowanie jest trudne z powodu zauważalnego niedeterminizmu, ale przy stosowaniu odpowiedniego podejścia do danego problemu i odpowiedniej biblioteki, która obsługuje to podejście, można uniknąć wielu problemów.
źródło
Najpierw nauczono mnie, że może wywoływać problemy, widząc prosty program, który uruchomił 2 wątki i kazał im drukować na konsoli w tym samym czasie od 1 do 100. Zamiast:
Otrzymujesz coś takiego:
Uruchom go ponownie, aby uzyskać zupełnie inne wyniki.
Większość z nas została przeszkolona do zakładania, że nasz kod będzie wykonywany sekwencyjnie. W przypadku większości wielowątkowości nie możemy tego uznać za rzecz oczywistą „po wyjęciu z pudełka”.
źródło
Spróbuj użyć kilku młotów do zacierania kilku gwoździ blisko siebie, jednocześnie bez komunikacji między tymi, którzy trzymają młoty ... (zakładając, że mają zasłonięte oczy).
Eskaluj to do budowy domu.
Teraz możesz spać w nocy wyobrażając sobie, że jesteś architektem. :)
źródło
Prosta część: używaj wielowątkowości ze współczesnymi funkcjami frameworków, systemów operacyjnych i sprzętu, takimi jak semafory, kolejki, liczniki blokowane, typy pudełek atomowych itp.
Część trudna: zaimplementuj funkcje samodzielnie, nie używając żadnych funkcji na pierwszym miejscu, może być tylko kilka bardzo ograniczonych możliwości sprzętowych, opierając się powiedzmy tylko na gwarancjach spójności taktowania na wielu rdzeniach.
źródło