Konkurentni i distribuirani sistemi
Sadržaj
Predgovor, xv
0. Terminologija i klasifikacija, 1
0.1 Paradigme konkurentnog programiranja, 1
0.2 Terminologija, 2
0.3 Klasifikacija konkurentnih i distribuiranih sistema, 4
0.4 Klasifikacija paradigmi konkurentnog programiranja, 5
0.5 Programiranje pomoću deljenih promenljivih, 7
0.6 Distribuirano programiranje, 8
0.7 Virtuelni prostori, 9
0.8 Programske niti, 10
0.9 Java, 11
0.9.1 Kreiranje i kontrola rada niti, 11
0.9.2 Sinhronizacija, 12
1. Uvod, 15
1.1 Deljeni objekti i sinhronizacija, 15
1.2 Nova priča о Alisi i Bobu, 17
1.2.1 Osobine uzajamnog isključivanja, 20
1.2.2 Naravoučenije, 20
1.3 Proizvođač potrošač, 21
1.4 Čitaoci i pisci, 23
1.5 Surova realnost paralelizacije, 24
2. Uzajamno isključivanje, 27
2.1 Vreme, 27
2.2 Kritične sekcije, 27
2.3 Rešenje za dve niti, 30
2.3.1 Klasa LockOne, 30
2.3.2 Klasa LockTwo, 31
2.3.3 Petersonov algoritam, 32
2.4 Filter algoritam, 34
2.5 Da li je ovo fer algoritam?, 37
2.6 Lamportov pekarski algoritam, 37
2.7 Vremenski žigovi, 39
2.8 Donja granica broja memorijskih lokacija, 42
3. Konkurentni objekti, 47
3.1 Konkurentnost i korektnost, 47
3.2 Sekvencijalni objekti, 50
3.3 Mima konzistentnost, 51
3.4 Sekvencijalna konzistentnost, 53
3.5 Linearizacija, 56
Tačke linearizacije, 56
Napomene, 56
3.6 Formalne definicije, 57
3.6.1 Linearizacija, 58
3.6.2 Kompoziciona linearizacija, 58
3.6.3 Neblokirajuće svojstvo, 59
3.7 Uslovi za progres, 60
3.7.1 Zavisni uslovi za progres, 61
3.8 Java memorijski model, 62
3.8.1 Ključevi i sinhronizacioni blokovi, 63
3.8.2 Volatile, 64
3.8.3 Final, 64
3.9 Napomene, 65
4. SpinLock i konflikt, 66
4.1 Realni svet, 66
4.2 Test And Set, 69
4.3 Revidirani TAS Spin Lock, 71
4.4 Eksponencijalni Backoff, 72
4.5 Redovi čekanja za niti, 74
4.5.1 Ključevi zasnovani na nizu, 74
4.5.2 CLHQueueLock, 77
4.5.3 MCS Queue Lock, 79
4.6 Queue Lock sa tajmautom, 81
4.7 Kompozitni ključ, 84
4.7.1 Kompozitni ključ sa brzom putanjom, 89
4.8 Klasteri i hijerarhijski ključevi, 92
4.8.1 Hijerarhijski Backoff, 92
4.8.2 Hijerarhijski CLH Queue ključ, 93
4.9 Jedan ključ za sve probleme, 98
4.10 Napomene, 98
4.11 Literatura, 99
5. Monitori, 101
5.1 Potreba za monitorima, 101
5.2 Ključevi i uslovi monitora, 101
5.2.1 Objekat uslova, 102
5.2.2 Problem propuštenog buđenja, 105
5.3 Čitaoci i pisci, 107
5.3.1 Jednostavan ReadersWriters ključ, 107
5.3.2 ReadersWriters fer ključ, 109
5.4 Reentrant ključ, 112
5.5 Semafori, 112
6. Barijere, 114
6.1 Uvod, 114
6.2 Implementacija barijere, 115
6.3 Barijera sa promenom pamosti, 116
6.4 Barijera sa kombinacionim stablom, 117
6.5 Barijera sa statičkim stablom, 120
6.6 Barijere sa detekcijom završetka, 121
7. Transakciona memorija, 125
7.1 Uvod, 125
7.1.1 Šta nije u redu sa zaključavanjem?, 125
7.1.2 Šta nije u redu sa compareAndSet()?, 125
7.1.3 Šta nije u redu sa kompozicijom?, 127
7.1.4 Šta mi možemo da uradimo po tom pitanju?, 128
7.2 Transakcije i atomičnost, 128
7.3 Softverska transakciona memorija, 131
7.3.1 Transakcije i transakcione niti, 134
7.3.2 Konkurentnost i zombi transakcije, 135
7.3.3 Atomični objekti, 136
7.3.4 Zavisni i nezavisni progres?, 138
7.3.5 Upravljanje konfliktima, 138
7.3.6 Implementacija atomičnih objekata, 140
7.3.7 Atomični objekti bez opstrukcije, 142
7.3.8 Atomični objekti sa ključevima, 145
7.4 Hardverska transakciona memorija, 152
7.4.1 Koherentnost keša, 152
7.4.2 Transakciona koherentnost keša, 153
7.4.3 Poboljšanja, 154
8. Multiprocesorsko raspoređivanje, 155
8.1 Uvod, 155
8.2 Analiza paralelizma, 161
8.3 Realistično multiprocesorsko raspoređivanje, 164
8.4 Raspodela opterećenja, 167
8.4.1 Krađaposlova, 167
8.4.2 Predaja kontrole i multiprogramiranje, 167
8.5 DEQueue sa krađom poslova, 168
8.5.1 Ograničeni DEQueue sa krađom poslova, 169
8.5.2 Neograničeni DEQueue sa krađom poslova, 172
8.5.3 Balansiranje poslova, 176
8.6 Raspoređivanje među heterogenim procesorima, 178
9. Distribuirano izračunavanje, 180
9.1 Distribuirani program, 180
9.1.1 Programiranje upotrebom soketa, 180
9.1.2 Povezivanje distribuiranih procesa, 183
9.1.3 Poziv udaljene metode (RMI), 187
9.2 Model distribuiranog izvršavanja, 191
9.2.1 Relacija kauzalnog prethođenja, 192
9.2.2 Logička i fizička konkurentnost, 193
9.3 Modeli komunikacionih mreža, 193
9.4 Globalno stanje distribuiranog sistema, 194
9.5 Preseci kod distribuiranog izračunavanja, 196
9.6 Konusi prošlosti i budućnosti događaja, 197
9.7 Modeli komunikacija među procesima, 198
9.7.1 Tranzijentne komunikacione primitive, 199
9.7.2 Sinhronizam procesora, 203
9.7.3 Biblioteke i standardi, 203
9.7.4 Sinhrona i asinhrona izvršavanja, 204
9.7.5 Literatura, 205
10. Logičko vreme, 207
10.1 Sistem logičkih časovnika, 208
10.1.1 Definicija, 208
10.1.2 Implementacija logičkih časovnika, 209
10.2 Skalarno vreme, 209
10.2.1 Definicija, 209
10.2.2 Osnovna svojstva, 210
10.3 Vektorsko vreme, 212
10.3.1 Definicija, 212
10.3.2 Osnovna svojstva, 213
10.3.3 Veličina vektorskih časovnika, 214
10.4 Implementacija vektorskih časovnika, 217
10.4.1 Diferencijalna tehnika (SinghalKshemkalyani), 218
10.4.2 Tehnika direktne zavisnosti (FowlerZwaenepoel), 220
10.4.3 Adaptivna tehnika (JardJourdan), 224
10.5 Matrično vreme, 227
10.5.1 Definicija, 227
10.5.2 Osnovne osobine, 229
10.6 Virtuelno vreme, 229
10.6.1 Definicija virtuelnog vremena, 230
10.6.2 Poređenje sa Lamportovim logičkim časovnicima, 231
10.6.3 Mehanizam vremenskog zakrivljenja, 232
10.6.4 Lokalni kontrolni mehanizam, 233
10.6.5 Globalni kontrolni mehanizam, 235
10.7 Sinhronizacija fizičkih časovnika, 238
10.7.1 Definicije i termionologija, 239
10.7.2 Odstupanja časovnika, 240
11. Globalno stanje i algoritmi za njegovo snimanje, 243
11.1 Uvod, 243
11.2 Model sistema i definicije, 245
11.2.1 Model sistema, 245
11.2.2 Konzistentno globalno stanje, 246
11.2.3 Interpretacija upotrebom preseka, 246
11.2.4 Problemi u snimanju globalnog stanja, 247
11.3 Algoritmi za FIFO kanale, 248
11.3.1 ChandyLamport algoritam, 248
11.3.2 Osobine snimljenog globalnog stanja, 250
11.3.3 Implementacija ChandyLamport algoritma, 252
11.4 Varijacije ChandyLamport algoritma, 255
11.4.1 SpezialettiKearns algoritam, 255
11.4.2 Venkatesan inkrementalni algoritam, 257
11.4.3 Helary talasni sinhronizacioni metod, 258
11.5 Algoritmi za neFIFO kanale, 258
11.5.1 LaiYang algoritam, 259
11.5.2 Li algoritam, 260
11.5.3 Mattern algoritam, 261
11.6 Snimanje stanja u sistemima sa kauzalnom isporukom, 263
11.6.1 Snimanje stanja procesa, 263
11.6.2 Snimanje stanja kanala kod AcharyaBadrinath algoritma, 263
11.6.3 Snimanje stanja kanala kod AlagarVenkatesan algoritma, 264
11.7 Praćenje globalnog stanja, 266
11.8 Potrebni i dovoljni uslovi, 266
11.9 Nalaženje konzistentnih globalnih snimaka, 270
11.9.1 Pronalaženje konzistentnih globalnih snimaka, 271
11.9.2 ManivannanNetzerSinghal algoritam, 274
11.9.3 Nalaženje Zputanja, 275
12. Osnovni distribuirani algoritmi, 278
12.1 Topološka apstrakcija i prekrivajuće mreže, 278
12.2 Klasifikacija i osnovni koncepti, 280
12.2.1 Izvršavanje aplikacija i koordinacionih algoritama, 280
12.2.2 Centralizovani i distribuirani algoritmi, 280
12.2.3 Simetrični i asimetrični algoritmi, 281
12.2.4 Anonimni algoritmi, 281
12.2.5 Uniformni algoritmi, 281
12.2.6 Adaptivni algoritmi, 282
12.2.7 Determinističko i nedeterminističko izvršavanje, 282
12.2.8 Inhibicija izvršavanja, 282
12.2.9 Sinhroni i asinhroni sistemi, 284
12.2.10 Online i offline algoritmi, 284
12.2.11 Modeli otkaza, 284
12.2.12 Algoritmi bez čekanja, 286
12.2.13 Komunikacioni kanali, 286
12.3 Metrike i mere kompleksnosti, 286
12.4 Programska struktura, 288
12.5 Elementami grafovski algoritmi, 289
12.5.1 Sinhroni algoritam razapinjućeg stabla sa jednim inicijatorom i plavljenjem, 289
12.5.2 Asinhroni algoritam razapinjućeg stabla sa jednim inicijatorom i plavljenjem, 291
12.5.3 Asinhroni algoritam razapinjućeg stabla sa konkurentnim inicijatorima i plavljenjem, 294
12.5.4 Asinhroni algoritam razapinjućeg stabla sa konkurentnim inicijatorima i DFS, 297
12.5.5 Brodkast i konvergekast na stablu, 299
12.5.6 Najkraći put sa jednim izvorom: sinhroni BellmanFord, 300
12.5.7 Rutiranje sa vektorom rastojanja, 301
12.5.8 Najkraći put sa jednim izvorom: asinhroni BellmanFord, 302
12.5.9 Najkraći putevi od svih izvora: asinhroni distribuirani FloydWarshall algoritam, 303
12.5.10 Algoritmi bez razapinjućeg stabla sa ograničenim plavljenjem. . 307
12.5.11 Razapinjuće stablo minimalne težine kod sinhronih sistema, 308
12.5.12 Algoritam razapinjućeg stabla minimalne težine kod asinhronih sistema, 313
12.5.13 Primeri implementacije, 314
12.6 Sinhronizatori, 317
12.6.1 Opšta zapažanja kod sinhronih i asinhronih algoritama, 317
12.6.2. Primeri implementacije, 323
12.7 Maksimalni nezavisni skup, 328
12.8 Povezani dominantni skup, 330
12.9 Kompaktne tabele rutiranja, 331
12.10 Izbor lidera, 333
12.11 Problemi u projektovanju grafovskih algoritama, 336
12.12 Problemi replikacije objekata, 336
12.12.1 Defmicija problema, 337
12.12.2 Prikaz algoritma, 337
12.12.3 Čitaoci i pisci, 338
12.12.4 Konvergencija ka šemi replikacije, 338
12.13 Pomoćni programi, 342
12.14 Literatura, 343
13. Redosled poruka i grupna komunikacija, 345
13.1 Paradigme redosleda poruka, 345
13.1.1 Asinhrona izvršavanja, 346
13.1.2 FIFO izvršavanje, 346
13.1.3 Izvršavanje kauzalnim redosledom, 347
13.1.4 Sinhrono izvršavanje, 349
13.2 Asinhrono izvršavanje sa sinhronom komunikacijom, 351
13.2.1 Izvršavanje ostvarivo sa sinhronom komunikacijom, 351
13.2.2 Hijerarhija paradigmi uređenja, 354
13.2.3 Simulacije, 355
13.3 Redosled u sinhronom programu na asinhronom sistemu, 356
13.3.1 Randevu, 357
13.3.2 Algoritam zabinami randevu, 358
13.4 Grupna komunikacija, 362
13.5 Kauzalno uređenje, 362
13.5.1 RaynalSchiperToueg algoritam, 363
13.5.2 KshemkalyaniSmghal algoritam, 365
13.6 Totalno uređenje, 371
13.6.1 Centralizovani algoritam zatotalno uređenje, 372
13.6.2 Trofazni distribuirani algoritam, 372
13.7 Nomenklatura za multikast, 376
13.8 Propagaciona stabla za multikast, 377
13.9 Klasifikacija multikast algoritama na aplikacionom nivou, 382
13.10 Semantika grupne komunikacije tolerantne na otkaze, 384
13.11 Distribuirani multikast algoritmi na mrežnom sloju, 386
13.11.1 Prosleđivanje reverznom putanjom za ograničeno plavljenje, 387
13.11.2 Štajnerova stabla, 387
13.11.3 Funkcija cene multikasta, 388
13.11.4 Štajnerova stabla sa ograničenim kašnjenjem, 389
13.11.5 Stabla na bazi jezgra, 392
14. Distribuirano uzajamno isključivanje, 393
14.1 Uvod, 393
14.2 Preliminarna razmatranja, 394
14.2.1 Model sistema, 394
14.2.2 Zahtevi koje mora da ispuni algoritam, 394
14.2.3 Metrike performansi, 395
14.3 Lamportov algoritam, 396
14.4 RicartAgrawala algoritam, 400
14.5 Singhal algoritam, 403
14.5.1 Opis algoritma, 405
14.5.2 Korektnost, 407
14.5.3 Analiza performansi, 408
14.6 LodhaKshemkalyani fer algoritam, 409
14.6.1 Model sistema, 409
14.6.2 Opis algoritma, 409
14.6.3 Kompleksnost poruka, 414
14.7 Uzajamno isključivanje na bazi kvoruma, 415
14.8 Maekawa algoritam, 416
14.8.1 Problem uzajamnog blokiranja, 417
14.9 AgarwalEl Abbadi algoritam na bazi kvoruma, 418
14.9.1 Konstrukcija kvoruma sa strukturom stabla, 419
14.9.2 Analiza algoritama za konstrukciju kvoruma sa strukturom stabla, 420
14.9.3 Validacija, 420
14.9.4 Primeri kvoruma sa strukturom stabla, 421
14.9.5 Algoritam za distribuirano uzajamno isključivanje, 422
14.9.6 Dokaz korektnosti, 423
14.10 Algoritmi na bazi tokena, 423
14.11 SuzukiKasami brodkast algoritam, 424
14.12 Raymond algoritam na bazi stabla, 426
14.12.1 Promenljiva HOLDER, 427
14.12.2 Funkcionisanje algoritma, 428
14.12.3 Opis algoritma, 429
14.12.4 Korektnost, 431
14.12.5 Analiza cene i performansi, 433
14.12.6 Inicijalizacija algoritma, 434
14.12.7 Otkazi i oporavak čvorova, 434
14.13 Literatura, 435
15. Distribuirana deljena memorija, 436
15.1 Apstrakcija i prednosti, 436
15.2 Modeli konzistentnosti memorije, 439
15.2.1 Striktna konzistentnost/atomična konzistentnost/mogućnost linearizacije, 440
15.2.2 Sekvencijalna konzistentnost, 444
15.2.3 Kauzalna konzistentnost, 447
15.2.4 PRAM (Pipelined RAM) ili konzistentnost procesora, 448
15.2.5 Spora memorija, 450
15.2.6 Hijerarhija modela konzistentnosti, 450
15.2.7 Modeli konzistentnosti kod sinhronizacionih instrukcija, 451
15.3 Uzajamno isključivanje u deljenoj memoriji, 453
15.3.1 Lamportov pekarski algoritam, 454
15.3.2 Lamportov WRWR mehanizam i brzo uzajamno isključivanje . .455
15.3.3 Hardverska podrška uzajamnom isključivanju, 458
15.4 Algoritmi bez čekanja, 460
15.5 Hijerarhija registara i simulacija izvršavanja bez čekanja, 461
15.5.1 SRSW bezbedan u MRSW bezbedan, 464
15.5.2 SRSW regularni u MRSW regulami, 464
15.5.3 Bulov MRSW bezbedni u celobrojni MRSW bezbedni, 465
15.5.4 Bulov MRSW bezbedan u Bulov MRSW regularan, 466
15.5.5 Bulov MRSW regulami u celobrojni MRSW regularni, 467
15.5.6 Bulov MRSW regulami u celobrojni MRSW atomični, 468
15.5.7 Celobrojni MRSW atomični u celobrojni MRMW atomični , .471
15.5.8 Celobrojni SRSW atomični u celobrojni MRSW atomični, 472
15.6 Deljeni objekat atomični snimak bez čekanja, 474
15.7 Literatura, 478
16. Dogovor i konsenzus, 480
16.1 Deflnicija problema, 480
16.1.1 Vizantijski dogovor i ostali problemi, 482
16.1.2 Ekvivalentnost problema i notacije, 483
16.2 Pregled rezultata, 483
16.3 Dogovor u sinhronim i asinhronim sistemima bez otkaza, 485
16.4 Dogovor u sinhromm sistemima sa otkazima, 486
16.4.1 Algoritam konsenzusa kod sinhronih sistema sa otkazima, 486
16.4.2 Konsenzus kod sinhronih sistema sa Vizantijskim otkazima, 487
16.5 Dogovor u asinhronim sistemima sa prenosom poruka i sa otkazima, 499
16.5.1 Rezultat nemogućnosti za problem konsenzusa, 499
16.5.2 Terminacioni pouzdani brodkast, 501
16.5.3 Predaja kod distribuiranih transakcija, 502
16.5.4 kset konsenzus, 502
16.5.5 Približni dogovor, 503
16.5.6 Problem preimenovanja, 509
16.5.7 Pouzdani brodkast, 515
16.6 Konsenzus bez čekanja kod asinhronih sistema sa deljenom memorijom, 515
16.6.1 Rezultat nemogućnosti, 515
16.6.2 Brojevi konsenzusa i hijerarhija, 518
16.6.3 Univerzalnost konsenzus objekata, 523
16.6.4 kset konsenzus u deljenoj memoriji, 528
16.6.5 Preimenovanje u deljenoj memoriji, 529
16.6.6 Preimenovanje kod deljene memorije upotrebom splitera, 531
16.7 Literatura, 533
17. Detekcija otkaza, 535
17.1 Uvod, 535
17.2 Nepouzdani detektori otkaza, 535
17.2.1 Model sistema, 536
17.2.2 Detektori otkaza, 537
17.2.3 Osobine kompletnosti i tačnosti, 537
17.2.4 Tipovi detektora otkaza, 539
17.2.5 Redukcija detektora otkaza, 540
17.2.6 Redukovanje slabog detektora W na jaki detektor S, 541
17.2.7 Redukcija slabog detektora sa odlaganjem 0W najaki detektor sa odlaganjem 0S, 543
17.3 Problem konsenzusa, 545
17.3.1 Rešenja problema konsenzusa, 545
17.3.2 Rešenje upotrebom jakog detektora otkaza S, 545
17.3.3 Rešenje upotrebom jakog detektora otkaza sa odlaganjem 0S, 547
17.4 Atomični brodkast, 550
17.5 Rešenje za atomični brodkast, 551
17.6 Najslabiji detektori otkaza koji rešavaju osnovni problem dogovora, 552
17.6.1 Realistični detektori otkaza, 553
17.6.2 Najslabiji detektor otkaza za konsenzus, 555
17.6.3 Najslabiji detektor otkaza za terminacioni pouzdani brodkast, 555
17.7 Implementacija detektora otkaza, 556
17.8 Protokol za adaptivnu detekciju otkaza, 558
17.9 Literatura, 562
Predgovor
Konkurentni i distribuirani sistemi više nisu egzotična oblast koja se povremeno izučava na master ili doktorskim studijama. Današnji programi su inherentno konkurentni i/ili distribuirani, počev od multiprocesorskih sistema, implementacija GUI (sistemi zasnovani na događajima), preko operativnih sistema, sistema u realnom vremenu pa sve do intemet aplikacija kao što su IoT, blockchain, P2P, itd. pri čemu tu treba uključiti infrastrukturu i samog intemeta (algoritmi i protokoli prenosa i шtiranja informacija).
Ova knjiga je nastala kao rezultat višegodišnjeg iskustva u nastavi na predmetu [8015] Konkurentni i distribuirani sistemi, koji se izvodi na studijskim programima osnovnih akademskih studija Računarske nauke i Računarsko inženjerstvo na Računarskom fakultetu Univerziteta Union u Beogradu. Iako je u početku bila namenjena isključivo kao udžbenik za ovaj predmet, ispostavilo se da ona ima i širu primenu. Knjiga može da koristi svakome ко želi da nauči kako konkurentni i distribuirani sistemi funkcionišu i zbog čega nekada, pored svog uloženog truda u njihov razvoj, ne funkcionišu. Potrebno predznanje studenata je na nivou analize sekvencijalnih algoritama. Poželjno je poznavanje funkcionisanja operativnih sistema i programskog jezika Java.
Primeri u knjizi, koji su dati u programskom jeziku Java, namenjeni su isključivo obrazovanju. Namerno su izostavljeni delovi koji proveravaju moguće greške, izuzetke i slično, a pojedini delovi koda i nisu u izvršnom obliku, već predstavljaju neku vrstu pseudo koda.
Knjiga nema nameru da bude sveobuhvatna. Opisani su osnovni pojmovi i principi iz kojih se dalje mogu izvoditi novi rezultati koji su specifični za datu primenu. Ukazano je na važnost generalizacije, apstrakcije i transparentnosti pojedinih rešenja, kao npr. kod transakcione memorije ili distribuirane deljene memorije.
Materijal za knjigu prikupljan je iz različitih izvora, pri čemu je u početku korišćen u okviru Beleški sa predavanja koje su bile osnovna literatura za predmet Konkurentni i distribuirani sistemi. Sasvim je moguće da se neke rečenice i fraze pojavljuju bez navođenja izvora. Autor je uložio maksimalan napor da naknadno citira upotrebljene resurse, pri čemu se citirana literatura nalazi na kraju pojedinih poglavlja. Svaka sličnost sa literaturom koja nije citirana je nenamerna i autor na te rezultate ne polaže nikakva autorska prava. U pojedinim delovima knjige korišćene su informacije i iz drugih knjiga koje se bave konkurentnim i distribuiranim sistemima, i to:
• Terminologija i klasifikacija preuzeta je iz knjige: Igor Ikodinović, Zoran Jovanović, Konkurentno programiranje: Teorijske osnove sa zbirkom rešenih zadataka, Akademska misao, 2004.
• Prvi deo knjige, koji se odnosi na konkurentne sisteme, zasnovan je na rezultatima koji su opisani u knjizi: Maurice Herlihy, Nir Shavit, The Art ofMultiprocessor Programming, Morgan Kaufmann, 2012.
• Drugi deo knjige, koji pokriva distribuirane sisteme, zasnovan je razultatima koji su opisani u knjizi: Ајау D. Kshemkalyani, Mukesh Singhal, Distributed Computing: Principles, Algorithms, and Systems, Cambridge University Press, 2008.
• Neki primeri u Javi za distribuirane sisteme preuzeti su iz knjige: Vijay K. Garg, Concurrent and Distributed Computing in Java, John Wiley & Sons, 2004.
Bez obzira na uloženi napor, u tekstu sigurno postoje greške. Mole se savesni čitaoci da greške koje pronađu prijave izdavaču, a autor im na tome unapred zahvaljuje.
U Beogradu, januara 2019. godine
Prof. dr Stevan A. Milinković
Detaljni podaci o knjiziNaslov: Konkurentni i distribuirani sistemi
Izdavač: CET
Strana: 580 (cb)
Povez: meki
Pismo: latinica
Format: B5
Godina izdanja: 2019
ISBN: 978-86-7991-412-5