CS207
Үйлдлийн систем
Лекц 6
Синхрончлал
А.Хүдэр, Э.Мөнхсүх
elearn.sict.edu.mn
Lec 6.29/20/10 Kubiatowicz CS162 ©UCB Fall 2010
ThreadFork(): Шинэ Хуулбар үүсгэх
• ThreadFork() бол хэрэглэгчийн түвшний функц ба
шинэ хуулбар үүсгээд бэлэн дараалалд байрлуулдаг.
– Бид өмнө CreateThread() гэж нэрлэж байсан.
• ThreadFork()-ийн аргументууд
– Програмын функцын заагч (fcnPtr)
– Аргументуудын массивын заагч (fcnArgPtr)
– Хуваарилах стэкийн хэмжээ
• Хэрэгжүүлэлт
– Дибаг-д зориулж аргументуудыг шалгах
– Кернел горим-д ороод дахин Аргументуудыг шалгах
– Шинээр стэк болон ХУБ-г хуваарилах
– ХУБ-д анхны утга оноож бэлэн жагсаалтанд байрлуулах
(Runnable).
Lec 6.39/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хуулбар яаж эхэлдэг вэ?
• Эцэст нь, run_new_thread() функц энэ ХУБ-ийг
сонгоод ThreadRoot()-ийн эхлэл руу буцна.
– Ингэж шинэ хуулбарыг эхлүүлнэ.
Stackgrowth A
B(while)
yield
run_new_thread
switch
ThreadRoot
Other Thread
ThreadRoot stub
New Thread
Lec 6.49/20/10 Kubiatowicz CS162 ©UCB Fall 2010
ThreadRoot() функц?
• ThreadRoot() функц нь хуулбарын функцын үндэс:
ThreadRoot() {
DoStartupHousekeeping();
UserModeSwitch(); /* enter user mode */
Call fcnPtr(fcnArgPtr);
ThreadFinish();
}
• Бэлтгэл ажиллагаа
– Хуулбарын эхэлсэн хугацааг
бүртгэнэ.
– Бусад статистикууд ...
• Хуулбарын ажиллагааны явцад
стэкийн хэмжээ ихсэж багасна.
• Хуулбар хамгийн сүүлд ThreadRoot() руу буцна.
Энэ нь ThreadFinish()-г дууддаг.
– ThreadFinish() хэрэглэгчийн түвшинд эхэлдэг.
ThreadRoot
Running Stack
Stackgrowth
Thread Code
Lec 6.59/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Праллель хуулбартай зөв систем
• Хэрэв диспетчер ямарч нөхцөлд төлөвлөж чаддаг бол, програм ямар ч
нөхцөлд ажиллана.
– Энийг тестэлж болох уу?
– Та програмаа ажиллаж байгааг яаж мэдэх вэ?
• Бие даасан хуулбарууд:
– Бусад хуулбартай ямар ч төлөв хуваалцахгүй
– Детерминистик  Оролтын төлөв үр дүнгээ тодорхойлно.
– Дахин үүсгэгддэг  Эхний нөхцөл болон I/O гаралтаа дахин
үүсэгдэг.
– Төлөвлөлтийн дарааллаас хамаарахгүй (Хэрэв switch()
ажиллаж байвал!!!)
• Хамтран ажиллаж байгаа хуулбарууд:
– Олон хуулбарууд төлвөө хуваалцана.
– Детерминистик биш
– Дахин үүсгэгддэггүй
• Детерминистик биш мөн дахин үүсгэгддэггүй гэдэг нь алдаанууд
тогтворгүй байдаг.
– Заримдаа “Heisenbugs” гэж дууддаг.
Lec 6.69/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Агуулга
• Давхцлын жишээ
• Синхрончлал хийхэд юу хэрэгтэй вэ?
• Зөв зүйтэй синхрончлалын тухай
Note: Some slides and/or pictures in the following are
adapted from slides ©2005 Silberschatz, Galvin, and Gagne
Note: Some slides and/or pictures in the following are
adapted from slides ©2005 Silberschatz, Galvin, and Gagne.
Many slides generated from my lecture notes by Kubiatowicz.
Lec 6.79/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Харилцаа нь зүгшрүүлэлтийг хүндэрүүлнэ
• Ямар нэг програм үнэнээсээ бие даасан байдаг уу?
– Пр бүр нь файл систем, ҮС нөөц, сүлжээ, гэх мэтийг хуваалцдаг.
– Жишээ: Алдаатай драйвераас болж A хуулбар нь “бие даасан” B
хуулбарыг гацаадаг.
• Та дахин үүсгэгдэх чадвараас хэрхэн хамаардагаа мэдэхгүй байх:
– Жишээ: Муу C-гийн компайлер.
» Зүгшрүүлэлтийн код нэмэхгүй бол таны бичиж байгаа C-гийн
програмын файл руу алдаа нэмдэг.
– Жишээ: Зүгшрүүлэлтийг их хэрэглэвэл стэк дүүрнэ.
• Детерминистик биш алдааг олоход үнэхээр хүнд
– Жишээ нь: кернел болон хэрэглэгчийн програм санах ойн
хуваарилалт
» Төлөвлөлтөөс хамаарна, төлөвөлөлт нь хугацаа болон бусад зүйлээс
хамаарна.
» Анхны UNIX нь маш олон детерминистик биш алдаатай байсан.
– Жишээ: Сонирхолтой I/O –хийж байгаа зүйл
» Хэрэглэгчийн бичиж байгаа үсгүүдээр нууц үг үүсгэхэд хэрэглэдэг.
Lec 6.89/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Яагаад хуулбаруудыг хамтран ажлуулдаг юм бэ?
• Хүмүүс бие биетэйгээ хамтран ажилладаг. Копьютер хүмүүсийн
амьдралд тусалдаг. Тиймээс компьютерүүд хамтран ажиллах ёстой.
– Үүнтэй адилаар хүмүүсийн дахин үүсгэгддэггүй/ детерминистик бус
байдал нь “Нарийн бодож боловрсуулсан төлөвлөгөөнд” саад болдог.
• Давуу тал 1: Нөөцийг хуваалцах
– Нэг компьютер, Олон хэрэглэгч
– Нэг банкны данснаас, олон ATMs-ээр мөнгө авах
» Хэрэв ATM шинэ шинэчлэлдэг бол яах вэ?
– Эмбэдэд систем (Роботын контрол: бугуй & саврууг зохицуулах)
• Давуу тал 2: Хурд нэмэх
– I/O болон Тооцооллыг зэрэг гүйцэтгэх
» Олон ялгаатай файлын систем урьдчилан уншдаг.
– Multiprocessors – програмаа параллель хэсгүүдэд хуваана.
• Давуу тал 3: Модулчилал
– Таны бодсоноос илүү чухал
– Том програмыг жижигхэн хэсгүүдэд хуваана.
» To compile, for instance, gcc calls cpp | cc1 | cc2 | as | ld
» Системийг өргөтгөхөд хялбар болгоно.
Lec 6.99/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хуулбартай вэб сервер
• Олон хуулбартай хувилбар:
serverLoop() {
connection = AcceptCon();
ThreadFork(ServiceWebPage(),connection);
}
• Хуулбартай хувилбарын давуу тал:
– Санах ойд байгаа файлын кэш, CGI скриптын үр дүн болон
бусад зүйлсийг хуваалцаж чадна.
– Хуулбар нь процесс үүсгэхээс маш хямд. Нэг хүсэлтийн
ачаалал багасна.
• Хэрэв нэгэн зэрэг олон хүсэлт ирвэл яах вэ?
Lec 6.109/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хуулбарын буфер
• Өмнөх хувилбарын асуудал: Хязгааргүй олон хуулбар
– Вэб сайт алдартай болвол – хурд буурна.
• Үүний оронд мултипрограмчлалын хамгийн их түвшнээр
хуулбарын буфер үүсгэж хуваарилна.
master() {
allocThreads(slave,queue);
while(TRUE) {
con=AcceptCon();
Enqueue(queue,con);
wakeUp(queue);
}
}
slave(queue) {
while(TRUE) {
con=Dequeue(queue);
if (con==null)
sleepOn(queue);
else
ServiceWebPage(con);
}
}
Master
Thread
Thread Pool
queue
Lec 6.119/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Банкны ATM сервер
• ATM серверийн асуудал:
– Хүсэлтүүдийг боловсруулах
– Өгөгдлийн санг эвдэхгүйгээр хийх
– Маш их мөнгийг бэлэн гаргахгүй
Lec 6.129/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Банкны ATM серверийн жишээ
• ATM-ийн сүлжээнээс ирсэн хүсэлтүүдийг боловсруулах
серверийн пр-г хэрэгжүүлэх гэж үзье:
BankServer() {
while (TRUE) {
ReceiveRequest(&op, &acctId, &amount);
ProcessRequest(op, acctId, amount);
}
}
ProcessRequest(op, acctId, amount) {
if (op == deposit) Deposit(acctId, amount);
else if …
}
Deposit(acctId, amount) {
acct = GetAccount(acctId); /* may use disk I/O */
acct->balance += amount;
StoreAccount(acct); /* Involves disk I/O */
}
• Үүнийг бид яаж хурдан болгож болох вэ?
– Нэгэн зэрэг олон хүсэлтийг боловсруулж эхлэх
– Үйл явдлаар удирдагдах (Тооцоолол болон I/O-г
давхцуулах)
– Олон хуулбар (олон-процесс, эсвэл Тооцоолол болон I/O-г
давхцуулах)
Lec 6.139/20/10 Kubiatowicz CS162 ©UCB Fall 2010
ATM-ийн серверийн ү/я-аар удирдагдах хувилбар
• Нэг CPU тэй гэж үзье.
– Тооцоолол болон I/O-г давхцуулахтай адилхан
– Хуулбар байхгүй үед бид ү/я-аар удирдагдах аргаар дахин
бичих хэрэгтэй.
• Жишээ нь:
BankServer() {
while(TRUE) {
event = WaitForNextEvent();
if (event == ATMRequest)
StartOnRequest();
else if (event == AcctAvail)
ContinueRequest();
else if (event == AcctStored)
FinishRequest();
}
}
– Хэрэв I/O-ийн блоклолтыг орхисон бол яах вэ?
– Хэрэв бид кодыг хэдэн зуун блоклогдсон хэсгүүдэд хуваавал
яах вэ?
– Энэ аргыг графикын програмчлалд хэрэглэдэг.
Lec 6.149/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хуулбар ашиглаж үүнийг хялбарчилж болох уу?
• Хуулбарыг ашиглан кодыг дахин бичилгүйгээр блокгүй
хэсгүүдэд хуваах заваар I/O болон тооцооллыг давхцуулж
болно.
– Нэг хүсэлтэнд нэг хуулбар
• Хүсэлтүүд нь боловсруулагдаж дуустлаа блоклогдоно:
Deposit(acctId, amount) {
acct = GetAccount(actId); /* May use disk I/O */
acct->balance += amount;
StoreAccount(acct); /* Involves disk I/O */
}
• Гэвч, дундын мэдээлэл эвдэр ч болно:
Thread 1 Thread 2
load r1, acct->balance
load r1, acct->balance
add r1, amount2
store r1, acct->balance
add r1, amount1
store r1, acct->balance
Lec 6.159/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Review: Multiprocessing vs Multiprogramming
• 2 хуулбар зэрэг ажиллах гэдэг юу гэсэн үг вэ?
– Төлөвлөгч хуулбаруудыг ямар ч дараааллаар ээлжлүүлэн
ажлуулж болно: FIFO, Санамсаргүй, …
– Диспетчер нь хуулбарыг дуустал эсвэл хугацаагаар сонгож
ажлуулна.
• Өмнө үзсэн: Hyperthreading
– Нэг команд дээр үндэслэн хуулбаруудыг давхцуулах
боломжтой
A B C
BA ACB C BMultiprogramming
A
B
C
Multiprocessing
Lec 6.169/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Асуудлыг доод түвшинд авч үзье
• Ихэнх үед хуулбарууд ялгаатай өгөгдөл дээр ажилладаг
учраас төлөвлөлтөөс хамаарахгүй:
Thread A Thread B
x = 1; y = 2;
• Гэвч, Доорх үед (y = 12):
Thread A Thread B
x = 1; y = 2;
x = y+1; y = y*2;
– x ямар утгатай болох вэ?
• Эсвэл, доор x ямар утгатай болох вэ?
Thread A Thread B
x = 1; x = 2;
– X нь 1 эсвэл 2 байж болно. (тодорхойгүй!)
– Сериал процессоруудын хувьд 3 ч байж болно:
» Хуулбар A 0001 руу бичив, мөн B 0010 бичив.
» Төлөвлөлтийн дараалал ABABABBA байхад 3 гарна!
Lec 6.179/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Атом үйлдлүүд
• Параллель програмыг ойлгохын тулд бид хуваагдахгүй
үйлдэл юу болохыг мэдэх хэрэгтэй!
• Атом үйлдлүүд: энэ үйлдэл нь нэг бол дуустал ажилладаг,
бүгд ажилладаггүй.
– Энэ бол хуваагддаггүй: Биелэлтийнх нь дунд зогсоож
болохгүй, мөн өөрчилж чадахгүй
– Бүтцийнх нь суурь блок – атом үйлдэл байхгүй бол хуулбарууд
хамтарч ажиллаж чадахгүй.
• Ихэнх машин дээр үгийг уншиж бичих үйлдэл нь атом
үйлдэл байдаг. (Жишээ нь: Хаяг авах болон утга олгох)
– Ийм учраас өмнөх слайд дээрх 3 гарагдаг жишээ
тохиолдохгүй.
• Ихэнх командууд атом биш байдаг.
– Давхар нарийвчлалтай бутархай тоог хадгалах үйлдэл
ихэвчлэн атом биш байна.
– VAX болон IBM 360 ҮС-д бүтэн массив хуулах команд байдаг
байсан.
Lec 6.189/20/10 Kubiatowicz CS162 ©UCB Fall 2010
• Хуулбартай програмын хуулбарын командууд нь ямар ч дарааллаар
ажилласан зөв ажиллах ёстой.
– Хамтран ажилладаг хуулбарууд нь тодорхойгүй бөгөөд дахин
сэргээхдэх мөн чанартай байна.
– Зохиомжийг сайн хийхгүй бол зүгшрүүлэлт хийхэд маш хэцүү!
• Жишээ: Therac-25
– Туяаны эмчилгээний аппарат
» Электрон туяа, электроны хурдас
-гуур, рентген туяаг програмаар
удирдана.
» Програмаар дозыг нь удирдна.
– Програмын алдаанаас болж хэдэн
өвчтнийг үхэлд хүрэгсэн.
» Хэд хэдэн дундын хувьсагчдын
өрсөлдөөнөөс. Бас програм хангамж-
-ийн муу дизайн
» “Засварлах үеийн өгөгдөл оруулах хурд нь алдаа гарах гол нөхцөл
болсон: Эмчилгээний зааврыг хурдан засварлах юм доз нь хэтэрдэг
байсан”
Зөв ажиллахад тавигдах шаардлага
Lec 6.199/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Олон дахин ашиглагдах сансрын хөлөг/Шаттл/-
ийн жишээ
• Сансрын шаттлын нислэг төлөвлөгдсөн хөөрөх цагаасаа 20 минутын
өмнө цуцлагджээ.
• Шаттл 5 компьютертэй:
– 4 нь “Primary Avionics
Software System” (PASS) ажлуулдаг
» Асинхрон болон бодит хугацааны
» Бүх удирдлагын системийг ажлуулна.
» Үр дүн 3аас 4 мл секундад синхрончилж харьцуулдаг.
– 5 дах систем бол “Backup Flight System” (BFS)
» Хэрэг болж магадгүй гээд синхрончлолж байна.
» PASS-ийг бичсэн багаас өөр програм хийсэн байна.
• BFS нь PASS-тай таараагүй учраас нислэгийг зогсоосон
– PASS нь тааруулалтаас нэг циклээр хоцрох магадлал 1/67 байна.
– PASS-ийн анхны утга олгох кодонд өөрчлөлт хийх үед алдаа
үүссэн.
» Таймерийн дараалалд хоцролттой эхлүүлэх хүсэлт байрлуулсан.
» Үүний үр дүнд таймерийн дараалал ТХ-ийн цагийг хэрэглэх үед
хоосон биш байсан.
– Өргөтгөсөн симуляцийн турш алдаа нь илрээгүй.
PASS
BFS
Lec 6.209/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Параллель програмын өөр нэг жишээ
• A, B хуулбар зэрэг ажиллаж байгаа:
– Нэг нь дундын тоолуурыг нэмэхийг оролдоно
– Нөгөө нь дундын тоолуурыг хорогдуулахыг оролдно
Thread A Thread B
i = 0; i = 0;
while (i < 10) while (i > -10)
i = i + 1; i = i – 1;
printf(“A wins!”); printf(“B wins!”);
• Санах ойгоос унших бичих үйлдэл нь атом үйлдлүүд.
Харин нэмэгдүүлэх ба хорогдуулах үйлдэл нь атом биш
үйлдлүүд гэж үзье.
• Хэн хожих вэ? Хэн ч хожиж болно.
• Аль нэг тал нь хожино гэсэн баталгаа байгаа юу? Яагаад?
• Хэрвээ 2 хуулбар ижилхэн CPU дээр ажиллаж байгаа бол
яах вэ? Энэ нь үүрд үргэлжлэх үү?
Lec 6.219/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Мултипроцессорын жишээг гар аргаар хийсэн
симуляци
• Дотоод давталт нь доорх хэлбэртэй харагдана:
Thread A Thread B
r1=0 load r1, M[i]
r1=0 load r1, M[i]
r1=1 add r1, r1, 1
r1=-1 sub r1, r1, 1
M[i]=1 store r1, M[i]
M[i]=-1 store r1, M[i]
• Гар аргаар хийсэн симуляци:
– A нь эхэлнэ.
– B нь араас нь хурдан явна.
– A нь дахиад 1 гэж бичнэ.
– B нь -1 гэж бичнэ.
– Тэгэхээр A нь “Би саяхан 1 гэж бичсэн дээ” гэж хэлнэ
• Нэг процессортой үед ийм юм болж болох уу?
– Тийм! Та болохгүй гэж бодож байгаа ч болох болно …
Lec 6.229/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Идэвхжүүлэх: “хэт их сүү”
• ҮС-ийн асуудлууд нь бодит амьдралын
асуудалтай төстэй байна.
– Бодит амьдрал дээрх асуудлыг ойлгоход тусалдаг
– Гэвч Компьютер нь хүмүүсээс тэнэг байдаг.
• Жишээ: Хүмүүс хоорондоо зохицдог:
Arrive home, put milk away3:30
Buy milk3:25
Arrive at storeArrive home, put milk away3:20
Leave for storeBuy milk3:15
Leave for store3:05
Look in Fridge. Out of milk3:00
Look in Fridge. Out of milkArrive at store3:10
Person BPerson ATime
Lec 6.239/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Тодорхойлолт
• Синхрончлол: атом үйлдлүүдийг хэрэглэн хуулбаруудын
хамтын ажиллагааг баталгаажуулах
– Одоохондоо бид унших бичих үйлдлийг атом үзэж байгаа.
– Зөвхөн унших бичих үйлдлийг ашиглаад ямар нэг зүйл
хийхэд хэцүү гэдгийг харуулах гэж байгаа.
• Солбицол: ямар нэг зүйлийг нэгэн зэрэг нэг хуулбар
хийнэ гэдгийг баталгаажуулна.
– Нэг хуулбар даалгавар биелүүлж байхдаа нөгөө хуулбараа
хориглоно.
• Эгзэгтэй муж: Нэг зэрэг нэг л хуулбар ажлуулж болох
кодын хэсэг. Нэг зэрэг нэг л хуулбар уг кодын хэсэг рүү
орж чадна.
– Эгзэгтэй муж бол солбицолын үр дүн юм.
– Эгзэгтэй муж бол солбицол нь нэг зүйлийг 2 талаас
тайлбарлаж байгаа болно.
Lec 6.249/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Тодорхойлолт /үргэлжлэл/
• Түгжих: хэн нэгэн ямар нэг зүйл хийхийг хязгаарлана.
– Эгзэгтэй муж руу орохын өмнө эсвэл дундын өгөгдөл рүү
хандахын өмнө түгжих
– Гарахдаа дундын өгөгдөл хандсны дараа түгжээгээ тайлах
– Түжээтэй бол хүлээх
» Чухал санаа: Бүх синхрончлол хүлээлтийг хэрэглэдэг.
• Жишээ нь: Сүүний асуудлыг шийдэхийн тулд
хөрөгчиндөө цоож хийж болно.
– Хэрвээ та сүү авахаа явах гэж байгаа бол цоожлоод
түлхүүрийг авч явна.
– Хурц шийдэл: Өрөөний хүн зөвхөн шүүс уух гэж байсан бол
уурлана.
– Мэдээж – Бид нар одоогоор түгжээг яаж хэрэглэхийг
мэдэхгүй байна.
Lec 6.259/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хэт их сүү: Зөв шийдлийн шинж чанар
• Параллель програмууд тодорхойгүй байдаг учраас
зөв эсэхэд нь анхаарах хэрэгтэй
– Эхлээд төлөвлөгөө гарга.
– Програмаа бичээд дараа нь үсээ зулгаадаг.
– Үүний оронд эхлээд бодоод, дараа нь програмаа бич
• “Хэт их сүү” асуудлын зөв шийдлийн шинж чанар нь
юу вэ???
– Хэзээ ч нэгээс олон хүн дэлгүүр явахгүй
– Хэрэгтэй бол хэн нэгэн нь худалдаж авна.
• Зөвхөн унших болон бичих атом үйлдлүүдийг
хэрэглэнэ.
Lec 6.269/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хэт их сүү: Шийдэл #1
• Бичиг үлдээж хэт их сүү авахаас зайлс хийх:
– Худалдаж авахынхаа өмнө бичиг үлдээнэ. ( “Түгжих”)
– Худалдаж авсныхаа дараа бичгээ авч хаях ( “Тайлах”)
– Хэрэв бичиг байвал худалдаж авахгүй (хүлээх)
• Компьютер дээр үүнийг авч үзье (Санах, Зөвхөн унших бичих үйлдэл
бол атом үйлдэл):
if (noMilk) {
if (noNote) {
leave Note;
buy milk;
remove note;
}
}
• Үр дүн?
– Хааяа хэт их сүүтэй болно.!
– Хуулбар нь сүү бичиг 2-г шалгаад сүү авахынхаа өмнө орчин
сольж болно.
• Энэ шийдэл нь асуудлыг улам хүндэрүүлнэ. Учир нь алдаа тогтворгүй
болно.
– Энэ нь үз үнэхээр хүнд болно.
– Диспетчер юу ч хийж байсан ажиллах ёстой!
Lec 6.279/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хэт их сүү: Шийдэл #1½
• Бичиг үлдээх нь хангалттай блок хийж чадахгүй байна.
– Үүнийг шийдэхийн тулд хамгийн эхэнд бичиг үлдээе.
• Өмнөх шийдлээр дахиж оролдож үзье:
leave Note;
if (noMilk) {
if (noNote) {
leave Note;
buy milk;
}
}
remove note;
• Одоо юу болох вэ?
– Хүмүүсийн хувьд бол ямар ч муу юм
болохгүй.
– Компьютерийн хувьд хэн ч хэзээ ч сүү авч
болохгүй.
Lec 6.289/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Хэт их сүү: Шийдэл #2
• Хүн болгон ялгаатай бичиг үлдээдэг бол яах вэ?
– Одоо бид шалгахаасаа өмнө бичиг үлдээнэ.
• Алгоритм доорх байдалтай:
Thread A Thread B
leave note A; leave note B;
if (noNote B) { if (noNoteA) {
if (noMilk) { if (noMilk) {
buy Milk; buy Milk;
} }
} }
remove note A; remove note B;
• Энэ ажиллах уу?
• Аль ч хуулбар сүү авахгүй байх боломжтой.
– Яг буруу үедээ бодлогор солилт хийснээс болоод хуулбар
болгон нөгөө хуулбараа худалдаж авах нь гэж бодно.
• Маш нуугдмал:
– Ийм юм болох магадлал маш бага. Хамгийн муу
тохиолдолд.
– Зөвхөн UNIX дээр болж магадгүй.
Lec 6.299/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Too Much Milk Solution #2: problem!
• I’m not getting milk, You’re getting milk
• This kind of lockup is called “starvation!”
Lec 6.309/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Too Much Milk Solution #3
• Here is a possible two-note solution:
Thread A Thread B
leave note A; leave note B;
while (note B) { //X if (noNote A) { //Y
do nothing; if (noMilk) {
} buy milk;
if (noMilk) { }
buy milk; }
} remove note B;
remove note A;
• Does this work? Yes. Both can guarantee that:
– It is safe to buy, or
– Other will buy, ok to quit
• At X:
– if no note B, safe for A to buy,
– otherwise wait to find out what will happen
• At Y:
– if no note A, safe for B to buy
– Otherwise, A is either buying or waiting for B to quit
Lec 6.319/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Solution #3 discussion
• Our solution protects a single “Critical-Section” piece of code
for each thread:
if (noMilk) {
buy milk;
}
• Solution #3 works, but it’s really unsatisfactory
– Really complex – even for this simple an example
» Hard to convince yourself that this really works
– A’s code is different from B’s – what if lots of threads?
» Code would have to be slightly different for each thread
– While A is waiting, it is consuming CPU time
» This is called “busy-waiting”
• There’s a better way
– Have hardware provide better (higher-level) primitives than
atomic load and store
– Build even higher-level programming abstractions on this new
hardware support
Lec 6.329/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Too Much Milk: Solution #4
• Suppose we have some sort of implementation of a lock (more
in a moment).
– Lock.Acquire() – wait until lock is free, then grab
– Lock.Release() – Unlock, waking up anyone waiting
– These must be atomic operations – if two threads are waiting for
the lock and both see it’s free, only one succeeds to grab the lock
• Then, our milk problem is easy:
milklock.Acquire();
if (nomilk)
buy milk;
milklock.Release();
• Once again, section of code between Acquire() and
Release() called a “Critical Section”
• Of course, you can make this even simpler: suppose you are
out of ice cream instead of milk
– Skip the test since you always need more ice cream.
Lec 6.339/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Where are we going with synchronization?
• We are going to implement various higher-level
synchronization primitives using atomic operations
– Everything is pretty painful if only atomic primitives are load
and store
– Need to provide primitives useful at user-level
Load/Store Disable Ints Test&Set Comp&Swap
Locks Semaphores Monitors Send/Receive
Shared Programs
Hardware
Higher-
level
API
Programs
Lec 6.349/20/10 Kubiatowicz CS162 ©UCB Fall 2010
Summary
• Concurrent threads are a very useful abstraction
– Allow transparent overlapping of computation and I/O
– Allow use of parallel processing when available
• Concurrent threads introduce problems when accessing shared
data
– Programs must be insensitive to arbitrary interleavings
– Without careful design, shared variables can become completely
inconsistent
• Important concept: Atomic Operations
– An operation that runs to completion or not at all
– These are the primitives on which to construct various
synchronization primitives
• Showed how to protect a critical section with only atomic load
and store  pretty complex!

Lec06 synchronization

  • 1.
  • 2.
    Lec 6.29/20/10 KubiatowiczCS162 ©UCB Fall 2010 ThreadFork(): Шинэ Хуулбар үүсгэх • ThreadFork() бол хэрэглэгчийн түвшний функц ба шинэ хуулбар үүсгээд бэлэн дараалалд байрлуулдаг. – Бид өмнө CreateThread() гэж нэрлэж байсан. • ThreadFork()-ийн аргументууд – Програмын функцын заагч (fcnPtr) – Аргументуудын массивын заагч (fcnArgPtr) – Хуваарилах стэкийн хэмжээ • Хэрэгжүүлэлт – Дибаг-д зориулж аргументуудыг шалгах – Кернел горим-д ороод дахин Аргументуудыг шалгах – Шинээр стэк болон ХУБ-г хуваарилах – ХУБ-д анхны утга оноож бэлэн жагсаалтанд байрлуулах (Runnable).
  • 3.
    Lec 6.39/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хуулбар яаж эхэлдэг вэ? • Эцэст нь, run_new_thread() функц энэ ХУБ-ийг сонгоод ThreadRoot()-ийн эхлэл руу буцна. – Ингэж шинэ хуулбарыг эхлүүлнэ. Stackgrowth A B(while) yield run_new_thread switch ThreadRoot Other Thread ThreadRoot stub New Thread
  • 4.
    Lec 6.49/20/10 KubiatowiczCS162 ©UCB Fall 2010 ThreadRoot() функц? • ThreadRoot() функц нь хуулбарын функцын үндэс: ThreadRoot() { DoStartupHousekeeping(); UserModeSwitch(); /* enter user mode */ Call fcnPtr(fcnArgPtr); ThreadFinish(); } • Бэлтгэл ажиллагаа – Хуулбарын эхэлсэн хугацааг бүртгэнэ. – Бусад статистикууд ... • Хуулбарын ажиллагааны явцад стэкийн хэмжээ ихсэж багасна. • Хуулбар хамгийн сүүлд ThreadRoot() руу буцна. Энэ нь ThreadFinish()-г дууддаг. – ThreadFinish() хэрэглэгчийн түвшинд эхэлдэг. ThreadRoot Running Stack Stackgrowth Thread Code
  • 5.
    Lec 6.59/20/10 KubiatowiczCS162 ©UCB Fall 2010 Праллель хуулбартай зөв систем • Хэрэв диспетчер ямарч нөхцөлд төлөвлөж чаддаг бол, програм ямар ч нөхцөлд ажиллана. – Энийг тестэлж болох уу? – Та програмаа ажиллаж байгааг яаж мэдэх вэ? • Бие даасан хуулбарууд: – Бусад хуулбартай ямар ч төлөв хуваалцахгүй – Детерминистик  Оролтын төлөв үр дүнгээ тодорхойлно. – Дахин үүсгэгддэг  Эхний нөхцөл болон I/O гаралтаа дахин үүсэгдэг. – Төлөвлөлтийн дарааллаас хамаарахгүй (Хэрэв switch() ажиллаж байвал!!!) • Хамтран ажиллаж байгаа хуулбарууд: – Олон хуулбарууд төлвөө хуваалцана. – Детерминистик биш – Дахин үүсгэгддэггүй • Детерминистик биш мөн дахин үүсгэгддэггүй гэдэг нь алдаанууд тогтворгүй байдаг. – Заримдаа “Heisenbugs” гэж дууддаг.
  • 6.
    Lec 6.69/20/10 KubiatowiczCS162 ©UCB Fall 2010 Агуулга • Давхцлын жишээ • Синхрончлал хийхэд юу хэрэгтэй вэ? • Зөв зүйтэй синхрончлалын тухай Note: Some slides and/or pictures in the following are adapted from slides ©2005 Silberschatz, Galvin, and Gagne Note: Some slides and/or pictures in the following are adapted from slides ©2005 Silberschatz, Galvin, and Gagne. Many slides generated from my lecture notes by Kubiatowicz.
  • 7.
    Lec 6.79/20/10 KubiatowiczCS162 ©UCB Fall 2010 Харилцаа нь зүгшрүүлэлтийг хүндэрүүлнэ • Ямар нэг програм үнэнээсээ бие даасан байдаг уу? – Пр бүр нь файл систем, ҮС нөөц, сүлжээ, гэх мэтийг хуваалцдаг. – Жишээ: Алдаатай драйвераас болж A хуулбар нь “бие даасан” B хуулбарыг гацаадаг. • Та дахин үүсгэгдэх чадвараас хэрхэн хамаардагаа мэдэхгүй байх: – Жишээ: Муу C-гийн компайлер. » Зүгшрүүлэлтийн код нэмэхгүй бол таны бичиж байгаа C-гийн програмын файл руу алдаа нэмдэг. – Жишээ: Зүгшрүүлэлтийг их хэрэглэвэл стэк дүүрнэ. • Детерминистик биш алдааг олоход үнэхээр хүнд – Жишээ нь: кернел болон хэрэглэгчийн програм санах ойн хуваарилалт » Төлөвлөлтөөс хамаарна, төлөвөлөлт нь хугацаа болон бусад зүйлээс хамаарна. » Анхны UNIX нь маш олон детерминистик биш алдаатай байсан. – Жишээ: Сонирхолтой I/O –хийж байгаа зүйл » Хэрэглэгчийн бичиж байгаа үсгүүдээр нууц үг үүсгэхэд хэрэглэдэг.
  • 8.
    Lec 6.89/20/10 KubiatowiczCS162 ©UCB Fall 2010 Яагаад хуулбаруудыг хамтран ажлуулдаг юм бэ? • Хүмүүс бие биетэйгээ хамтран ажилладаг. Копьютер хүмүүсийн амьдралд тусалдаг. Тиймээс компьютерүүд хамтран ажиллах ёстой. – Үүнтэй адилаар хүмүүсийн дахин үүсгэгддэггүй/ детерминистик бус байдал нь “Нарийн бодож боловрсуулсан төлөвлөгөөнд” саад болдог. • Давуу тал 1: Нөөцийг хуваалцах – Нэг компьютер, Олон хэрэглэгч – Нэг банкны данснаас, олон ATMs-ээр мөнгө авах » Хэрэв ATM шинэ шинэчлэлдэг бол яах вэ? – Эмбэдэд систем (Роботын контрол: бугуй & саврууг зохицуулах) • Давуу тал 2: Хурд нэмэх – I/O болон Тооцооллыг зэрэг гүйцэтгэх » Олон ялгаатай файлын систем урьдчилан уншдаг. – Multiprocessors – програмаа параллель хэсгүүдэд хуваана. • Давуу тал 3: Модулчилал – Таны бодсоноос илүү чухал – Том програмыг жижигхэн хэсгүүдэд хуваана. » To compile, for instance, gcc calls cpp | cc1 | cc2 | as | ld » Системийг өргөтгөхөд хялбар болгоно.
  • 9.
    Lec 6.99/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хуулбартай вэб сервер • Олон хуулбартай хувилбар: serverLoop() { connection = AcceptCon(); ThreadFork(ServiceWebPage(),connection); } • Хуулбартай хувилбарын давуу тал: – Санах ойд байгаа файлын кэш, CGI скриптын үр дүн болон бусад зүйлсийг хуваалцаж чадна. – Хуулбар нь процесс үүсгэхээс маш хямд. Нэг хүсэлтийн ачаалал багасна. • Хэрэв нэгэн зэрэг олон хүсэлт ирвэл яах вэ?
  • 10.
    Lec 6.109/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хуулбарын буфер • Өмнөх хувилбарын асуудал: Хязгааргүй олон хуулбар – Вэб сайт алдартай болвол – хурд буурна. • Үүний оронд мултипрограмчлалын хамгийн их түвшнээр хуулбарын буфер үүсгэж хуваарилна. master() { allocThreads(slave,queue); while(TRUE) { con=AcceptCon(); Enqueue(queue,con); wakeUp(queue); } } slave(queue) { while(TRUE) { con=Dequeue(queue); if (con==null) sleepOn(queue); else ServiceWebPage(con); } } Master Thread Thread Pool queue
  • 11.
    Lec 6.119/20/10 KubiatowiczCS162 ©UCB Fall 2010 Банкны ATM сервер • ATM серверийн асуудал: – Хүсэлтүүдийг боловсруулах – Өгөгдлийн санг эвдэхгүйгээр хийх – Маш их мөнгийг бэлэн гаргахгүй
  • 12.
    Lec 6.129/20/10 KubiatowiczCS162 ©UCB Fall 2010 Банкны ATM серверийн жишээ • ATM-ийн сүлжээнээс ирсэн хүсэлтүүдийг боловсруулах серверийн пр-г хэрэгжүүлэх гэж үзье: BankServer() { while (TRUE) { ReceiveRequest(&op, &acctId, &amount); ProcessRequest(op, acctId, amount); } } ProcessRequest(op, acctId, amount) { if (op == deposit) Deposit(acctId, amount); else if … } Deposit(acctId, amount) { acct = GetAccount(acctId); /* may use disk I/O */ acct->balance += amount; StoreAccount(acct); /* Involves disk I/O */ } • Үүнийг бид яаж хурдан болгож болох вэ? – Нэгэн зэрэг олон хүсэлтийг боловсруулж эхлэх – Үйл явдлаар удирдагдах (Тооцоолол болон I/O-г давхцуулах) – Олон хуулбар (олон-процесс, эсвэл Тооцоолол болон I/O-г давхцуулах)
  • 13.
    Lec 6.139/20/10 KubiatowiczCS162 ©UCB Fall 2010 ATM-ийн серверийн ү/я-аар удирдагдах хувилбар • Нэг CPU тэй гэж үзье. – Тооцоолол болон I/O-г давхцуулахтай адилхан – Хуулбар байхгүй үед бид ү/я-аар удирдагдах аргаар дахин бичих хэрэгтэй. • Жишээ нь: BankServer() { while(TRUE) { event = WaitForNextEvent(); if (event == ATMRequest) StartOnRequest(); else if (event == AcctAvail) ContinueRequest(); else if (event == AcctStored) FinishRequest(); } } – Хэрэв I/O-ийн блоклолтыг орхисон бол яах вэ? – Хэрэв бид кодыг хэдэн зуун блоклогдсон хэсгүүдэд хуваавал яах вэ? – Энэ аргыг графикын програмчлалд хэрэглэдэг.
  • 14.
    Lec 6.149/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хуулбар ашиглаж үүнийг хялбарчилж болох уу? • Хуулбарыг ашиглан кодыг дахин бичилгүйгээр блокгүй хэсгүүдэд хуваах заваар I/O болон тооцооллыг давхцуулж болно. – Нэг хүсэлтэнд нэг хуулбар • Хүсэлтүүд нь боловсруулагдаж дуустлаа блоклогдоно: Deposit(acctId, amount) { acct = GetAccount(actId); /* May use disk I/O */ acct->balance += amount; StoreAccount(acct); /* Involves disk I/O */ } • Гэвч, дундын мэдээлэл эвдэр ч болно: Thread 1 Thread 2 load r1, acct->balance load r1, acct->balance add r1, amount2 store r1, acct->balance add r1, amount1 store r1, acct->balance
  • 15.
    Lec 6.159/20/10 KubiatowiczCS162 ©UCB Fall 2010 Review: Multiprocessing vs Multiprogramming • 2 хуулбар зэрэг ажиллах гэдэг юу гэсэн үг вэ? – Төлөвлөгч хуулбаруудыг ямар ч дараааллаар ээлжлүүлэн ажлуулж болно: FIFO, Санамсаргүй, … – Диспетчер нь хуулбарыг дуустал эсвэл хугацаагаар сонгож ажлуулна. • Өмнө үзсэн: Hyperthreading – Нэг команд дээр үндэслэн хуулбаруудыг давхцуулах боломжтой A B C BA ACB C BMultiprogramming A B C Multiprocessing
  • 16.
    Lec 6.169/20/10 KubiatowiczCS162 ©UCB Fall 2010 Асуудлыг доод түвшинд авч үзье • Ихэнх үед хуулбарууд ялгаатай өгөгдөл дээр ажилладаг учраас төлөвлөлтөөс хамаарахгүй: Thread A Thread B x = 1; y = 2; • Гэвч, Доорх үед (y = 12): Thread A Thread B x = 1; y = 2; x = y+1; y = y*2; – x ямар утгатай болох вэ? • Эсвэл, доор x ямар утгатай болох вэ? Thread A Thread B x = 1; x = 2; – X нь 1 эсвэл 2 байж болно. (тодорхойгүй!) – Сериал процессоруудын хувьд 3 ч байж болно: » Хуулбар A 0001 руу бичив, мөн B 0010 бичив. » Төлөвлөлтийн дараалал ABABABBA байхад 3 гарна!
  • 17.
    Lec 6.179/20/10 KubiatowiczCS162 ©UCB Fall 2010 Атом үйлдлүүд • Параллель програмыг ойлгохын тулд бид хуваагдахгүй үйлдэл юу болохыг мэдэх хэрэгтэй! • Атом үйлдлүүд: энэ үйлдэл нь нэг бол дуустал ажилладаг, бүгд ажилладаггүй. – Энэ бол хуваагддаггүй: Биелэлтийнх нь дунд зогсоож болохгүй, мөн өөрчилж чадахгүй – Бүтцийнх нь суурь блок – атом үйлдэл байхгүй бол хуулбарууд хамтарч ажиллаж чадахгүй. • Ихэнх машин дээр үгийг уншиж бичих үйлдэл нь атом үйлдэл байдаг. (Жишээ нь: Хаяг авах болон утга олгох) – Ийм учраас өмнөх слайд дээрх 3 гарагдаг жишээ тохиолдохгүй. • Ихэнх командууд атом биш байдаг. – Давхар нарийвчлалтай бутархай тоог хадгалах үйлдэл ихэвчлэн атом биш байна. – VAX болон IBM 360 ҮС-д бүтэн массив хуулах команд байдаг байсан.
  • 18.
    Lec 6.189/20/10 KubiatowiczCS162 ©UCB Fall 2010 • Хуулбартай програмын хуулбарын командууд нь ямар ч дарааллаар ажилласан зөв ажиллах ёстой. – Хамтран ажилладаг хуулбарууд нь тодорхойгүй бөгөөд дахин сэргээхдэх мөн чанартай байна. – Зохиомжийг сайн хийхгүй бол зүгшрүүлэлт хийхэд маш хэцүү! • Жишээ: Therac-25 – Туяаны эмчилгээний аппарат » Электрон туяа, электроны хурдас -гуур, рентген туяаг програмаар удирдана. » Програмаар дозыг нь удирдна. – Програмын алдаанаас болж хэдэн өвчтнийг үхэлд хүрэгсэн. » Хэд хэдэн дундын хувьсагчдын өрсөлдөөнөөс. Бас програм хангамж- -ийн муу дизайн » “Засварлах үеийн өгөгдөл оруулах хурд нь алдаа гарах гол нөхцөл болсон: Эмчилгээний зааврыг хурдан засварлах юм доз нь хэтэрдэг байсан” Зөв ажиллахад тавигдах шаардлага
  • 19.
    Lec 6.199/20/10 KubiatowiczCS162 ©UCB Fall 2010 Олон дахин ашиглагдах сансрын хөлөг/Шаттл/- ийн жишээ • Сансрын шаттлын нислэг төлөвлөгдсөн хөөрөх цагаасаа 20 минутын өмнө цуцлагджээ. • Шаттл 5 компьютертэй: – 4 нь “Primary Avionics Software System” (PASS) ажлуулдаг » Асинхрон болон бодит хугацааны » Бүх удирдлагын системийг ажлуулна. » Үр дүн 3аас 4 мл секундад синхрончилж харьцуулдаг. – 5 дах систем бол “Backup Flight System” (BFS) » Хэрэг болж магадгүй гээд синхрончлолж байна. » PASS-ийг бичсэн багаас өөр програм хийсэн байна. • BFS нь PASS-тай таараагүй учраас нислэгийг зогсоосон – PASS нь тааруулалтаас нэг циклээр хоцрох магадлал 1/67 байна. – PASS-ийн анхны утга олгох кодонд өөрчлөлт хийх үед алдаа үүссэн. » Таймерийн дараалалд хоцролттой эхлүүлэх хүсэлт байрлуулсан. » Үүний үр дүнд таймерийн дараалал ТХ-ийн цагийг хэрэглэх үед хоосон биш байсан. – Өргөтгөсөн симуляцийн турш алдаа нь илрээгүй. PASS BFS
  • 20.
    Lec 6.209/20/10 KubiatowiczCS162 ©UCB Fall 2010 Параллель програмын өөр нэг жишээ • A, B хуулбар зэрэг ажиллаж байгаа: – Нэг нь дундын тоолуурыг нэмэхийг оролдоно – Нөгөө нь дундын тоолуурыг хорогдуулахыг оролдно Thread A Thread B i = 0; i = 0; while (i < 10) while (i > -10) i = i + 1; i = i – 1; printf(“A wins!”); printf(“B wins!”); • Санах ойгоос унших бичих үйлдэл нь атом үйлдлүүд. Харин нэмэгдүүлэх ба хорогдуулах үйлдэл нь атом биш үйлдлүүд гэж үзье. • Хэн хожих вэ? Хэн ч хожиж болно. • Аль нэг тал нь хожино гэсэн баталгаа байгаа юу? Яагаад? • Хэрвээ 2 хуулбар ижилхэн CPU дээр ажиллаж байгаа бол яах вэ? Энэ нь үүрд үргэлжлэх үү?
  • 21.
    Lec 6.219/20/10 KubiatowiczCS162 ©UCB Fall 2010 Мултипроцессорын жишээг гар аргаар хийсэн симуляци • Дотоод давталт нь доорх хэлбэртэй харагдана: Thread A Thread B r1=0 load r1, M[i] r1=0 load r1, M[i] r1=1 add r1, r1, 1 r1=-1 sub r1, r1, 1 M[i]=1 store r1, M[i] M[i]=-1 store r1, M[i] • Гар аргаар хийсэн симуляци: – A нь эхэлнэ. – B нь араас нь хурдан явна. – A нь дахиад 1 гэж бичнэ. – B нь -1 гэж бичнэ. – Тэгэхээр A нь “Би саяхан 1 гэж бичсэн дээ” гэж хэлнэ • Нэг процессортой үед ийм юм болж болох уу? – Тийм! Та болохгүй гэж бодож байгаа ч болох болно …
  • 22.
    Lec 6.229/20/10 KubiatowiczCS162 ©UCB Fall 2010 Идэвхжүүлэх: “хэт их сүү” • ҮС-ийн асуудлууд нь бодит амьдралын асуудалтай төстэй байна. – Бодит амьдрал дээрх асуудлыг ойлгоход тусалдаг – Гэвч Компьютер нь хүмүүсээс тэнэг байдаг. • Жишээ: Хүмүүс хоорондоо зохицдог: Arrive home, put milk away3:30 Buy milk3:25 Arrive at storeArrive home, put milk away3:20 Leave for storeBuy milk3:15 Leave for store3:05 Look in Fridge. Out of milk3:00 Look in Fridge. Out of milkArrive at store3:10 Person BPerson ATime
  • 23.
    Lec 6.239/20/10 KubiatowiczCS162 ©UCB Fall 2010 Тодорхойлолт • Синхрончлол: атом үйлдлүүдийг хэрэглэн хуулбаруудын хамтын ажиллагааг баталгаажуулах – Одоохондоо бид унших бичих үйлдлийг атом үзэж байгаа. – Зөвхөн унших бичих үйлдлийг ашиглаад ямар нэг зүйл хийхэд хэцүү гэдгийг харуулах гэж байгаа. • Солбицол: ямар нэг зүйлийг нэгэн зэрэг нэг хуулбар хийнэ гэдгийг баталгаажуулна. – Нэг хуулбар даалгавар биелүүлж байхдаа нөгөө хуулбараа хориглоно. • Эгзэгтэй муж: Нэг зэрэг нэг л хуулбар ажлуулж болох кодын хэсэг. Нэг зэрэг нэг л хуулбар уг кодын хэсэг рүү орж чадна. – Эгзэгтэй муж бол солбицолын үр дүн юм. – Эгзэгтэй муж бол солбицол нь нэг зүйлийг 2 талаас тайлбарлаж байгаа болно.
  • 24.
    Lec 6.249/20/10 KubiatowiczCS162 ©UCB Fall 2010 Тодорхойлолт /үргэлжлэл/ • Түгжих: хэн нэгэн ямар нэг зүйл хийхийг хязгаарлана. – Эгзэгтэй муж руу орохын өмнө эсвэл дундын өгөгдөл рүү хандахын өмнө түгжих – Гарахдаа дундын өгөгдөл хандсны дараа түгжээгээ тайлах – Түжээтэй бол хүлээх » Чухал санаа: Бүх синхрончлол хүлээлтийг хэрэглэдэг. • Жишээ нь: Сүүний асуудлыг шийдэхийн тулд хөрөгчиндөө цоож хийж болно. – Хэрвээ та сүү авахаа явах гэж байгаа бол цоожлоод түлхүүрийг авч явна. – Хурц шийдэл: Өрөөний хүн зөвхөн шүүс уух гэж байсан бол уурлана. – Мэдээж – Бид нар одоогоор түгжээг яаж хэрэглэхийг мэдэхгүй байна.
  • 25.
    Lec 6.259/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хэт их сүү: Зөв шийдлийн шинж чанар • Параллель програмууд тодорхойгүй байдаг учраас зөв эсэхэд нь анхаарах хэрэгтэй – Эхлээд төлөвлөгөө гарга. – Програмаа бичээд дараа нь үсээ зулгаадаг. – Үүний оронд эхлээд бодоод, дараа нь програмаа бич • “Хэт их сүү” асуудлын зөв шийдлийн шинж чанар нь юу вэ??? – Хэзээ ч нэгээс олон хүн дэлгүүр явахгүй – Хэрэгтэй бол хэн нэгэн нь худалдаж авна. • Зөвхөн унших болон бичих атом үйлдлүүдийг хэрэглэнэ.
  • 26.
    Lec 6.269/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хэт их сүү: Шийдэл #1 • Бичиг үлдээж хэт их сүү авахаас зайлс хийх: – Худалдаж авахынхаа өмнө бичиг үлдээнэ. ( “Түгжих”) – Худалдаж авсныхаа дараа бичгээ авч хаях ( “Тайлах”) – Хэрэв бичиг байвал худалдаж авахгүй (хүлээх) • Компьютер дээр үүнийг авч үзье (Санах, Зөвхөн унших бичих үйлдэл бол атом үйлдэл): if (noMilk) { if (noNote) { leave Note; buy milk; remove note; } } • Үр дүн? – Хааяа хэт их сүүтэй болно.! – Хуулбар нь сүү бичиг 2-г шалгаад сүү авахынхаа өмнө орчин сольж болно. • Энэ шийдэл нь асуудлыг улам хүндэрүүлнэ. Учир нь алдаа тогтворгүй болно. – Энэ нь үз үнэхээр хүнд болно. – Диспетчер юу ч хийж байсан ажиллах ёстой!
  • 27.
    Lec 6.279/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хэт их сүү: Шийдэл #1½ • Бичиг үлдээх нь хангалттай блок хийж чадахгүй байна. – Үүнийг шийдэхийн тулд хамгийн эхэнд бичиг үлдээе. • Өмнөх шийдлээр дахиж оролдож үзье: leave Note; if (noMilk) { if (noNote) { leave Note; buy milk; } } remove note; • Одоо юу болох вэ? – Хүмүүсийн хувьд бол ямар ч муу юм болохгүй. – Компьютерийн хувьд хэн ч хэзээ ч сүү авч болохгүй.
  • 28.
    Lec 6.289/20/10 KubiatowiczCS162 ©UCB Fall 2010 Хэт их сүү: Шийдэл #2 • Хүн болгон ялгаатай бичиг үлдээдэг бол яах вэ? – Одоо бид шалгахаасаа өмнө бичиг үлдээнэ. • Алгоритм доорх байдалтай: Thread A Thread B leave note A; leave note B; if (noNote B) { if (noNoteA) { if (noMilk) { if (noMilk) { buy Milk; buy Milk; } } } } remove note A; remove note B; • Энэ ажиллах уу? • Аль ч хуулбар сүү авахгүй байх боломжтой. – Яг буруу үедээ бодлогор солилт хийснээс болоод хуулбар болгон нөгөө хуулбараа худалдаж авах нь гэж бодно. • Маш нуугдмал: – Ийм юм болох магадлал маш бага. Хамгийн муу тохиолдолд. – Зөвхөн UNIX дээр болж магадгүй.
  • 29.
    Lec 6.299/20/10 KubiatowiczCS162 ©UCB Fall 2010 Too Much Milk Solution #2: problem! • I’m not getting milk, You’re getting milk • This kind of lockup is called “starvation!”
  • 30.
    Lec 6.309/20/10 KubiatowiczCS162 ©UCB Fall 2010 Too Much Milk Solution #3 • Here is a possible two-note solution: Thread A Thread B leave note A; leave note B; while (note B) { //X if (noNote A) { //Y do nothing; if (noMilk) { } buy milk; if (noMilk) { } buy milk; } } remove note B; remove note A; • Does this work? Yes. Both can guarantee that: – It is safe to buy, or – Other will buy, ok to quit • At X: – if no note B, safe for A to buy, – otherwise wait to find out what will happen • At Y: – if no note A, safe for B to buy – Otherwise, A is either buying or waiting for B to quit
  • 31.
    Lec 6.319/20/10 KubiatowiczCS162 ©UCB Fall 2010 Solution #3 discussion • Our solution protects a single “Critical-Section” piece of code for each thread: if (noMilk) { buy milk; } • Solution #3 works, but it’s really unsatisfactory – Really complex – even for this simple an example » Hard to convince yourself that this really works – A’s code is different from B’s – what if lots of threads? » Code would have to be slightly different for each thread – While A is waiting, it is consuming CPU time » This is called “busy-waiting” • There’s a better way – Have hardware provide better (higher-level) primitives than atomic load and store – Build even higher-level programming abstractions on this new hardware support
  • 32.
    Lec 6.329/20/10 KubiatowiczCS162 ©UCB Fall 2010 Too Much Milk: Solution #4 • Suppose we have some sort of implementation of a lock (more in a moment). – Lock.Acquire() – wait until lock is free, then grab – Lock.Release() – Unlock, waking up anyone waiting – These must be atomic operations – if two threads are waiting for the lock and both see it’s free, only one succeeds to grab the lock • Then, our milk problem is easy: milklock.Acquire(); if (nomilk) buy milk; milklock.Release(); • Once again, section of code between Acquire() and Release() called a “Critical Section” • Of course, you can make this even simpler: suppose you are out of ice cream instead of milk – Skip the test since you always need more ice cream.
  • 33.
    Lec 6.339/20/10 KubiatowiczCS162 ©UCB Fall 2010 Where are we going with synchronization? • We are going to implement various higher-level synchronization primitives using atomic operations – Everything is pretty painful if only atomic primitives are load and store – Need to provide primitives useful at user-level Load/Store Disable Ints Test&Set Comp&Swap Locks Semaphores Monitors Send/Receive Shared Programs Hardware Higher- level API Programs
  • 34.
    Lec 6.349/20/10 KubiatowiczCS162 ©UCB Fall 2010 Summary • Concurrent threads are a very useful abstraction – Allow transparent overlapping of computation and I/O – Allow use of parallel processing when available • Concurrent threads introduce problems when accessing shared data – Programs must be insensitive to arbitrary interleavings – Without careful design, shared variables can become completely inconsistent • Important concept: Atomic Operations – An operation that runs to completion or not at all – These are the primitives on which to construct various synchronization primitives • Showed how to protect a critical section with only atomic load and store  pretty complex!

Editor's Notes

  • #8 Adding printf statements can cause stack overruns or changing timing/interleaving What if non-deterministic error only occurs once a week? You’re pulling all-nighters to find it, your eyelids droop, and whiz, the error happens and you missed it.
  • #17 X could be (13, 5, 3)
  • #23 You’re sitting in class, hot day, milk does a body good. Go home, no milk, so go to store Roommate leaves class late because prof is more long-winded than I am. Has same idea, but result is too much milk! Problem: two cooperating threads, not cooperating properly