Processer och trådar: Att arbeta ensam kontra att använda självminnen

📖 10min read

Kunskaper som 1 minuts självintroduktion för intervju

”Vad är skillnaden mellan en process och en tråd?”

När jag var arbetssökande ingick den här frågan alltid i de 10 vanligaste intervjufrågorna. Jag svarade som en maskin.

”En process är ett pågående program, och en tråd är en flödesenhet som körs inom en process. Processer delar inte resurser, men trådar delar resurser.”

Intervjuaren nickade och jag antog att jag förstod detta koncept perfekt. Men tills jag stötte på ”Concurrency Issue” i praktiken hade jag ingen aning om den sanna rädslan som innehöll den meningen.

”Varför är det meningen att antalet visningar ska öka med 100, men det bara ökar med 98?” ”Varför slutar webbplatsen när jag laddar ner Excel?”

Min kod var perfekt när jag körde den ensam, men det blev en enda röra när flera användare kom in samtidigt. Jag trodde att det skulle lösas genom att helt enkelt öka antalet ”arbetare”, men jag visste inte att när antalet arbetare ökar, ökar kostnaderna för att hantera dem (Context Switching) exponentiellt.

När du arbetar ensam är det lugnt, men när du arbetar med andra börjar krig.

Fabrik och arbetare i digitalt logistikcenter

Låt oss återgå till vår världsbild av ”digitalt logistikcenter”. Att köra ett program på en dator är som att sätta upp en ”fabrik” i ett distributionscenter.

1. Process: Självständig arbetsplats

2. Ämne: Arbetare i verkstaden

Trådar har både ett ”delat utrymme (hög)” och ett ”oberoende utrymme (stack)”.

[Kodverifiering] Tragedi för delning (samtidighetsproblem)

”Trådar delar resurser.” Detta kan låta som en fördel i intervjurummet, men i praktiken kan det vara fröet till ”katastrof”.

Kommer du ihåg ”Högen” vi lärde oss förra gången? Trådar delar detta högområde. Det betyder att tråd B kan komma och skriva över data som tråd A arbetar med.

Detta kallas ”Race Condition”. Låt oss kontrollera det med kod.

public class RaceConditionTest {
    static int count = 0; // Delad variabel lagrad i Heap

    public static void main(String[] args) throws InterruptedException {
        // Anstall tva arbetare (tradar)
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) count++;
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) count++;
        });

        t1.start(); // Starta arbetet!
        t2.start(); // Starta arbetet!
        
        t1.join(); // Vanta tills de slutar jobba
        t2.join(); // Vanta tills de slutar jobba
        
        System.out.println("Slutresultat: " + count);
    }
}

Förväntat resultat: Eftersom två personer har lagts till 10 000 gånger bör resultatet vara 20 000.

Faktiskt resultat: 15 482, 18 931… Värdet är olika varje gång jag kör det, och 20 000 visas inte.

Orsak:

Detta är identiteten för buggen som ”ibland tuggas data” i praktiken. Det här är en tragedi som inträffade när arbetare rörde samma bok utan att prata med varandra.

Om vi jämför den här situationen med en databas (DB), är det samma sak som ”en situation där flera frågor flygs samtidigt utan en transaktion.” Om saldot på bankkontot samtidigt ändras utan lås inträffar en fruktansvärd olycka där pengarna förångas. Precis som vi skyddar data med ROLLBACK eller COMMIT i DB, är en låsanordning som Synchronized absolut nödvändig på kodnivån.

Avvägning i praktiken: multi-process kontra multi-thread

Så när och vad ska du använda i praktiken?

1. Valfri Chrome-webbläsare: Flerprocess

I gamla Internet Explorer stängdes hela webbläsaren av när en flik stannade (flertrådad metod). Chrome lanserar dock varje flik som en ”separat process (fabrik)”.

2. Val av webbserver (Spring, Node.js, etc.): Flertrådad

Servern måste hantera tusentals förfrågningar. Om du bygger en process (fabrik) för varje begäran kommer servern att krascha. Så det bearbetas genom att ha många trådar (arbetare) i en process.

Skulle du hellre bygga en säker men dyr ”fästning” eller flyga en snabb men farlig ”drönare”?

Stängning: Självbränning kommer med ansvar

Idag har vi tittat på ”processer och trådar”, hur arbetare arbetar.

Nu vet du att termen ”samtidsfrågor” inte bara är en intervjuterm. Många trådarbetare rör sig ständigt in och ut ur ett delat lager som kallas Heapen. Det är färdigheten hos en backend-utvecklare att skapa ordning i detta kaos.

Men vänta, om det finns många arbetare, hur bestämmer du vem som ska göra vems arbete först? Hur hanterar en fabrikschef (OS) hundratals arbetare? Nästa gång kommer vi att prata om fabrikschefens mest besvärliga uppgift, ”Schemaläggning och kontextbyte.”

Lämna en kommentar