Spacerujmy po lesie programowania współbieżności w języku programowania rdzy. Należy pamiętać, że jest to artykuł nie został zaprojektowany jako kompletny przewodnik po programowaniu współbieżności. Służy jedynie jako podstawa do rozszerzania i tworzenia bardziej złożonych aplikacji.
Procesy i wątki
Kiedy piszemy normalny program i wykonujemy go w systemie docelowym, system operacyjny hosta wykonuje kod w procesie. Proces odnosi się do jednostki określonego wykonywalnego.
Jednak w nowoczesnych systemach i aplikacjach masz części tego samego kodu uruchomionego jednocześnie za pomocą wątków.
W większości przypadków często usłyszysz termin zastosowany wielokresta. Dzieje się tak, ponieważ zasadniczo odradzamy wiele wątków i pozwalamy im działać równolegle do siebie.
Weźmy podstawowy program, aby zilustrować, jak działa normalny program i jak wykorzystywać współbieżność, aby go ulepszyć.
Rozważ program z dwiema pętlami, jak pokazano:
Użyj std :: wątek;W powyższym przykładowym kodzie mamy dwie pętle, które iterują od 0 do 5. Jednak w każdej iteracji śpimy przez 1000 milisekund.
Metoda wątku :: Sleep pozwala nam uśpić określony wątek na określony czas trwania.
Jeśli uruchomisz powyższy kod, zauważysz, że pierwsza pętla czeka na zakończenie drugiej pętli, zanim zacznie się uruchomić.
Dzieje się tak, ponieważ obie pętle znajdują się w jednym wątku.
Jeśli chcemy, aby obie pętle działały jednocześnie, musimy umieścić je w różnych wątkach.
Rust Utwórz wątek
Możemy tworzyć nowe wątki za pomocą modułu wątku. Jest częścią standardowej biblioteki i zapewnia nam pakiet narzędzi i funkcji do pracy z wątkami.
Możemy go zaimportować za pomocą instrukcji:
Użyj std :: wątek;Potrzebujemy również modułu czasu trwania z wątku czasu. Możemy to zaimportować jako:
Użyj std :: czas :: czas trwaniaAby utworzyć nowy wątek w rdzy, użyj metody wątku ::. Ta metoda zamyka się jako argument.
Zamknięcie w tym przypadku definiuje kod do uruchomienia wewnątrz wątku.
Składnia jest jak pokazana poniżej:
Wątek :: Spawn (|| zamknięcie)Udoskonalmy poprzedni kod i umieść każdy konstrukt w osobnym wątku. Przykładowy kod jest tak, jak pokazano:
Użyj std :: wątek;W powyższym przykładowym programie tworzymy nowy wątek za pomocą funkcji wątku :: Spawn i przekazujemy pierwszą pętlę jako zamknięcie.
W głównym wątku uruchamiamy drugą pętlę. To pozwala obie pętle działać jednocześnie. Kod powyżej powinien zwrócić dane wyjściowe jako:
0Co się stanie, jeśli główny wątek wyjdzie przed zakończeniem wątku „wewnętrznego”? Przykładem jest to, jak pokazano poniżej:
Użyj std :: wątek;W tym przykładzie główny wątek wymaga mniej czasu na sen, a zatem ukończy się szybciej przed zakończeniem wewnętrznego wątku.
W takim przypadku wewnętrzny wątek będzie działał tylko podczas działania głównego wątku. Powyższy kod zwróci niekompletne dane wyjściowe jako:
0Wynika to z faktu, że wątek „wewnętrzny” jest zakończony przed zakończeniem.
Uchwyty łączające rdzę
Widzieliśmy, jak wątek zachowuje się, jeśli główny wątek kończy się przed jego zakończeniem. Możemy dołączyć do dwóch uchwytów, aby rozwiązać taką sprawę i pozwolić, aby drugi wątek czekał na inny.
Połączenie uchwytów pozwoli głównej wątkowi czekać na inne wątki przed zakończeniem.
Aby dołączyć do uchwytów, używamy metody połączenia, jak pokazano w poniższej składni:
LET HANDED_NAME = WHERNE :: Spawn (Closure);Na nowo zdefiniujmy nasz przykład pętli, w którym główny wątek kończy się wcześnie.
Użyj std :: wątek;W powyższym przykładowym kodzie tworzymy zmienną uchwytu, która utrzymuje wątek. Następnie dołączamy do wątku za pomocą metody łączenia ().
Metoda rozpakowania pozwala nam obsługiwać błędy.
Ponieważ główny wątek śpi przez krótszy czas, należy go ukończyć przed wątkiem „wewnętrznym”. Powinien jednak poczekać, aż drugi wątek wyjdzie z powodu metody połączenia.
Wyjście jest tak, jak pokazano:
0Należy zauważyć, że główny wątek wysyła wszystkie wartości w krótkim czasie i czeka na zakończenie drugiego wątku.
Zamknięcie ruchu nić rdzy
Być może zauważyłeś słowo kluczowe przenoszenia wewnątrz zamknięcia wątku w naszym poprzednim przykładzie. Zamknięcie ruchu jest używane z metodą wątku :: Spawn, aby umożliwić udostępnianie danych między wątkami.
Korzystając z słowa kluczowego ruchu, możemy pozwolić wątkowi przenieść własność wartości do innego wątku.
Weźmy przykład programu poniżej:
Użyj std :: wątek;W powyższym kodzie deklarujemy tablicę o nazwie ARR w głównym wątku. Następnie odradzamy nowy wątek bez zamknięcia ruchu.
Uwaga: Ponieważ staramy się uzyskać dostęp do tablicy ARR i uczynić ją częścią środowiska zamknięcia, kompilacja zawiedzie, ponieważ nie jest dostępna w tym wątku.
Możemy użyć słowa kluczowego ruchu, aby wymusić zamknięcie wątku, aby przejąć własność tablicy.
Możemy naprawić powyższy kod, dodając zamknięcie ruchu, jak pokazano:
Użyj std :: wątek;To pozwala wątkowi przejąć własność tablicy i ją iterować. To powinno powrócić:
1Wniosek
To były podstawy jednoczesnego programowania w języku programowania rdzy. Chociaż ten artykuł służy jako konkretna podstawa współbieżności rdzy, nie obejmuje zaawansowanych koncepcji. Szczegółowe informacje możesz sprawdzić dokumentację.