OSTEP chatper 30

This commit is contained in:
ridethepig 2023-04-11 20:48:42 +08:00
parent 36d188acfa
commit 6994bb7a34
2 changed files with 834 additions and 11 deletions

View File

@ -1173,5 +1173,644 @@
:height 1382.4}),
:page 358},
:content {:text " the lock is not acquired during the first spin phase, a second phase is entered, where the caller is put to sleep, and only woken up when the lock becomes free later."},
:properties {:color "yellow"}}
{:id #uuid "643525b0-e245-489b-877d-a2a1d63e7ea6",
:page 361,
:position {:bounding {:x1 174.14286422729492,
:y1 325.0178756713867,
:x2 645.9385185241699,
:y2 360.44644927978516,
:width 806.3999999999999,
:height 1209.6},
:rects ({:x1 174.14286422729492,
:y1 325.0178756713867,
:x2 645.9385185241699,
:y2 360.44644927978516,
:width 806.3999999999999,
:height 1209.6}),
:page 361},
:content {:text "Lock-based Concurrent Data Structures"},
:properties {:color "yellow"}}
{:id #uuid "643525e5-fb85-48d4-905a-2a88b9ac0b0d",
:page 361,
:position {:bounding {:x1 108.35714340209961,
:y1 815.107177734375,
:x2 298.91018295288086,
:y2 835.6786193847656,
:width 806.3999999999999,
:height 1209.6},
:rects ({:x1 108.35714340209961,
:y1 815.107177734375,
:x2 298.91018295288086,
:y2 835.6786193847656,
:width 806.3999999999999,
:height 1209.6}),
:page 361},
:content {:text "Concurrent Counters"},
:properties {:color "yellow"}}
{:id #uuid "64352751-d9bd-4d5e-a8ba-cd18f86b1a15",
:page 363,
:position {:bounding {:x1 156.65179443359375,
:y1 746.232177734375,
:x2 260.2728805541992,
:y2 762.8036193847656,
:width 806.3999999999999,
:height 1209.6},
:rects ({:x1 156.65179443359375,
:y1 746.232177734375,
:x2 260.2728805541992,
:y2 762.8036193847656,
:width 806.3999999999999,
:height 1209.6}),
:page 363},
:content {:text "perfect scaling"},
:properties {:color "yellow"}}
{:id #uuid "64352794-d7c8-42f9-8321-f874967cebf2",
:page 363,
:position {:bounding {:x1 376.82144927978516,
:y1 967.5000305175781,
:x2 523.3794326782227,
:y2 984.0715026855469,
:width 806.3999999999999,
:height 1209.6},
:rects ({:x1 376.82144927978516,
:y1 967.5000305175781,
:x2 523.3794326782227,
:y2 984.0715026855469,
:width 806.3999999999999,
:height 1209.6}),
:page 363},
:content {:text "approximate counter"},
:properties {:color "yellow"}}
{:id #uuid "643530d8-9d09-4c8a-9e92-47dfe814ef50",
:page 367,
:position {:bounding {:x1 116.09400177001953,
:y1 446.52679443359375,
:x2 350.7183532714844,
:y2 468.24107360839844,
:width 864,
:height 1296},
:rects ({:x1 116.09400177001953,
:y1 446.52679443359375,
:x2 350.7183532714844,
:y2 468.24107360839844,
:width 864,
:height 1296}),
:page 367},
:content {:text "Concurrent Linked Lists"},
:properties {:color "yellow"}}
{:id #uuid "64353237-4b74-4148-b7c1-5854d83a18c7",
:page 369,
:position {:bounding {:x1 255.12501525878906,
:y1 1018.0357666015625,
:x2 451.5310516357422,
:y2 1035.7500610351562,
:width 864,
:height 1296},
:rects ({:x1 255.12501525878906,
:y1 1018.0357666015625,
:x2 451.5310516357422,
:y2 1035.7500610351562,
:width 864,
:height 1296}),
:page 369},
:content {:text "hand-over-hand locking"},
:properties {:color "yellow"}}
{:id #uuid "64353353-9de2-421b-967d-dc80a597eecd",
:page 370,
:position {:bounding {:x1 171.89286422729492,
:y1 644.6607360839844,
:x2 361.0623435974121,
:y2 666.3750305175781,
:width 864,
:height 1296},
:rects ({:x1 171.89286422729492,
:y1 644.6607360839844,
:x2 361.0623435974121,
:y2 666.3750305175781,
:width 864,
:height 1296}),
:page 370},
:content {:text "Concurrent Queues"},
:properties {:color "yellow"}}
{:id #uuid "6435360d-c176-494a-9d61-b1fd0107a9bd",
:page 372,
:position {:bounding {:x1 171.89286041259766,
:y1 604.0268096923828,
:x2 395.03311920166016,
:y2 625.7411041259766,
:width 864,
:height 1296},
:rects ({:x1 171.89286041259766,
:y1 604.0268096923828,
:x2 395.03311920166016,
:y2 625.7411041259766,
:width 864,
:height 1296}),
:page 372},
:content {:text "Concurrent Hash Table"},
:properties {:color "yellow"}}
{:id #uuid "6435363d-c697-42a6-bfd0-8a2332cef394",
:page 372,
:position {:bounding {:x1 0,
:y1 445.1428680419922,
:x2 745.5475311279297,
:y2 804.1607513427734,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 445.1428680419922,
:x2 0,
:y2 466.28575134277344,
:width 864,
:height 1296}
{:x1 532.4713592529297,
:y1 766.5178680419922,
:x2 745.5475311279297,
:y2 784.2321624755859,
:width 864,
:height 1296}
{:x1 171.89286041259766,
:y1 786.4464569091797,
:x2 632.3166275024414,
:y2 804.1607513427734,
:width 864,
:height 1296}),
:page 372},
:content {:text "instead of having a single lock for the entire structure, it uses a lock per hash bucket"},
:properties {:color "yellow"}}
{:id #uuid "6435365a-b5d6-46fc-a9a1-25b0d23aa529",
:page 372,
:position {:bounding {:x1 564.7891998291016,
:y1 1059.107177734375,
:x2 651.2378387451172,
:y2 1076.8214721679688,
:width 864,
:height 1296},
:rects ({:x1 564.7891998291016,
:y1 1059.107177734375,
:x2 651.2378387451172,
:y2 1076.8214721679688,
:width 864,
:height 1296}),
:page 372},
:content {:text "ubiquitous "},
:properties {:color "green"}}
{:id #uuid "6435367f-dd9e-449d-b0e4-3d8c9e14f6c2",
:page 373,
:position {:bounding {:x1 320.9654083251953,
:y1 875.2946624755859,
:x2 378.3458709716797,
:y2 893.0089569091797,
:width 864,
:height 1296},
:rects ({:x1 320.9654083251953,
:y1 875.2946624755859,
:x2 378.3458709716797,
:y2 893.0089569091797,
:width 864,
:height 1296}),
:page 373},
:content {:text "humble "},
:properties {:color "green"}}
{:id #uuid "643536c8-fc05-4bbe-8d1d-0f4f6d1c4fee",
:page 376,
:position {:bounding {:x1 443.3345642089844,
:y1 585.2410888671875,
:x2 497.6003112792969,
:y2 602.9553833007812,
:width 864,
:height 1296},
:rects ({:x1 443.3345642089844,
:y1 585.2410888671875,
:x2 497.6003112792969,
:y2 602.9553833007812,
:width 864,
:height 1296}),
:page 376},
:content {:text "sloppy "},
:properties {:color "green"}}
{:id #uuid "643537d3-7d01-442b-b47e-59433c2aa6db",
:page 378,
:position {:bounding {:x1 596.2246246337891,
:y1 701.2500305175781,
:x2 659.0949554443359,
:y2 718.9643249511719,
:width 864,
:height 1296},
:rects ({:x1 596.2246246337891,
:y1 701.2500305175781,
:x2 659.0949554443359,
:y2 718.9643249511719,
:width 864,
:height 1296}),
:page 378},
:content {:text "grossly "},
:properties {:color "green"}}
{:id #uuid "643537ff-1028-4725-8d7a-c0338cc946d3",
:page 378,
:position {:bounding {:x1 293.5893096923828,
:y1 858.1875305175781,
:x2 445.99464416503906,
:y2 881.6160888671875,
:width 864,
:height 1296},
:rects ({:x1 293.5893096923828,
:y1 858.1875305175781,
:x2 445.99464416503906,
:y2 881.6160888671875,
:width 864,
:height 1296}),
:page 378},
:content {:text "condition variable"},
:properties {:color "yellow"}}
{:id #uuid "64353882-7697-4c16-8e53-c8f59ea256c1",
:page 378,
:position {:bounding {:x1 0,
:y1 477.1428642272949,
:x2 747.7302322387695,
:y2 981.2410888671875,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 477.1428642272949,
:x2 0,
:y2 498.28572273254395,
:width 864,
:height 1296}
{:x1 0,
:y1 493.1428656578064,
:x2 0,
:y2 514.2857241630554,
:width 864,
:height 1296}
{:x1 0,
:y1 509.14286613464355,
:x2 0,
:y2 530.2857246398926,
:width 864,
:height 1296}
{:x1 0,
:y1 525.1428661346436,
:x2 0,
:y2 546.2857246398926,
:width 864,
:height 1296}
{:x1 0,
:y1 541.1428680419922,
:x2 0,
:y2 562.2857246398926,
:width 864,
:height 1296}
{:x1 484.25003814697266,
:y1 858.1875305175781,
:x2 641.9464797973633,
:y2 881.6160888671875,
:width 864,
:height 1296}
{:x1 463.3002700805664,
:y1 859.8482360839844,
:x2 747.3339920043945,
:y2 877.7767944335938,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 879.7768249511719,
:x2 745.5433197021484,
:y2 897.7053833007812,
:width 864,
:height 1296}
{:x1 262.47322845458984,
:y1 898.0357360839844,
:x2 341.1931381225586,
:y2 921.4643249511719,
:width 864,
:height 1296}
{:x1 531.553596496582,
:y1 898.0357360839844,
:x2 601.7216262817383,
:y2 921.4643249511719,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 899.6964416503906,
:x2 747.192024230957,
:y2 917.6250305175781,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 919.6250305175781,
:x2 745.5449066162109,
:y2 937.5535888671875,
:width 864,
:height 1296}
{:x1 717.848274230957,
:y1 937.8928833007812,
:x2 747.7302322387695,
:y2 961.3214721679688,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 939.5535888671875,
:x2 747.7302322387695,
:y2 957.482177734375,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 957.8125305175781,
:x2 229.24837493896484,
:y2 981.2410888671875,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 960.669677734375,
:x2 371.48160552978516,
:y2 978.5982360839844,
:width 864,
:height 1296}),
:page 378},
:content {:text "A condition variable is an explicit queue that threads can put themselves on when some state of execution(i.e., some condition) is not as desired (by waiting on the condition); some other thread, when it changes said state, can then wake one (or more) of those waiting threads and thus allow them to continue (by signaling on the condition). "},
:properties {:color "yellow"}}
{:id #uuid "643538d5-9ea3-4399-9fa2-d75fdf0e1dd4",
:page 378,
:position {:bounding {:x1 0,
:y1 653.1428680419922,
:x2 747.631721496582,
:y2 1116.6607666015625,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 653.1428680419922,
:x2 0,
:y2 674.2857284545898,
:width 864,
:height 1296}
{:x1 650.6428909301758,
:y1 1079.0178833007812,
:x2 747.631721496582,
:y2 1096.9464721679688,
:width 864,
:height 1296}
{:x1 171.8928680419922,
:y1 1098.9464721679688,
:x2 594.3628997802734,
:y2 1116.6607666015625,
:width 864,
:height 1296}),
:page 378},
:content {:text "wait() call is executed when a thread wishes to put itself to sleep;"},
:properties {:color "yellow"}}
{:id #uuid "643538de-cc40-4dd2-8f03-9492004f209b",
:page 379,
:position {:bounding {:x1 0,
:y1 541.1428680419922,
:x2 689.7592334747314,
:y2 885.2500305175781,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 541.1428680419922,
:x2 0,
:y2 562.2857360839844,
:width 864,
:height 1296}
{:x1 116.09822273254395,
:y1 847.607177734375,
:x2 689.7592334747314,
:y2 865.3214721679688,
:width 864,
:height 1296}
{:x1 116.09822273254395,
:y1 867.5357360839844,
:x2 633.988603591919,
:y2 885.2500305175781,
:width 864,
:height 1296}),
:page 379},
:content {:text "is executed when a thread has changed something in the program and thus wants to wake a sleeping thread waiting on this condition. S"},
:properties {:color "yellow"}}
{:id #uuid "64353eb8-8ed8-4680-a3c0-91608b429408",
:page 379,
:position {:bounding {:x1 360.32312774658203,
:y1 1098.9464721679688,
:x2 409.81058502197266,
:y2 1116.6607666015625,
:width 864,
:height 1296},
:rects ({:x1 360.32312774658203,
:y1 1098.9464721679688,
:x2 409.81058502197266,
:y2 1116.6607666015625,
:width 864,
:height 1296}),
:page 379},
:content {:text "stems "},
:properties {:color "green"}}
{:id #uuid "643547c5-1613-49e9-899e-0e86f59a1462",
:page 380,
:position {:bounding {:x1 0,
:y1 285.14288330078125,
:x2 747.3582305908203,
:y2 563.0268249511719,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 285.14288330078125,
:x2 0,
:y2 306.2857437133789,
:width 864,
:height 1296}
{:x1 541.1089324951172,
:y1 525.1786041259766,
:x2 747.3582305908203,
:y2 543.107177734375,
:width 864,
:height 1296}
{:x1 171.89286422729492,
:y1 545.0982513427734,
:x2 745.9600219726562,
:y2 563.0268249511719,
:width 864,
:height 1296}),
:page 380},
:content {:text "uses a while loop instead of just an if statement when deciding whether to wait on the condition."},
:properties {:color "yellow"}}
{:id #uuid "64354974-adea-4b20-90f4-a12ebe1e4d5b",
:page 382,
:position {:bounding {:x1 279.43043518066406,
:y1 543.8750152587891,
:x2 506.8169403076172,
:y2 567.3035888671875,
:width 864,
:height 1296},
:rects ({:x1 279.4464416503906,
:y1 543.8750152587891,
:x2 443.5089569091797,
:y2 567.3035888671875,
:width 864,
:height 1296}
{:x1 279.43043518066406,
:y1 545.5357208251953,
:x2 506.8169403076172,
:y2 563.4642944335938,
:width 864,
:height 1296}),
:page 382},
:content {:text "producer/consumer problem,"},
:properties {:color "yellow"}}
{:id #uuid "64354cc4-14c5-408d-b879-7d4d011b2b5c",
:page 385,
:position {:bounding {:x1 294.6515197753906,
:y1 1077.3572082519531,
:x2 425.10882568359375,
:y2 1100.7857971191406,
:width 864,
:height 1296},
:rects ({:x1 294.6785888671875,
:y1 1077.3572082519531,
:x2 425.10882568359375,
:y2 1100.7857971191406,
:width 864,
:height 1296}
{:x1 294.6515197753906,
:y1 1079.0179138183594,
:x2 294.65740966796875,
:y2 1096.7322082519531,
:width 864,
:height 1296}),
:page 385},
:content {:text "Mesa semantics"},
:properties {:color "yellow"}}
{:id #uuid "64354d46-4286-44fd-9e82-2ba562a50f25",
:page 386,
:position {:bounding {:x1 0,
:y1 477.1428909301758,
:x2 746.0656509399414,
:y2 818.6518249511719,
:width 864,
:height 1296},
:rects ({:x1 0,
:y1 477.1428909301758,
:x2 0,
:y2 498.28575134277344,
:width 864,
:height 1296}
{:x1 171.89286422729492,
:y1 779.3482666015625,
:x2 308.99941635131836,
:y2 802.7768249511719,
:width 864,
:height 1296}
{:x1 308.9821548461914,
:y1 781.0089721679688,
:x2 746.0656509399414,
:y2 798.9375610351562,
:width 864,
:height 1296}
{:x1 171.89286422729492,
:y1 800.9375610351562,
:x2 693.3923149108887,
:y2 818.6518249511719,
:width 864,
:height 1296}),
:page 386},
:content {:text "Hoare semantics, is harder to build but provides a stronger guarantee that the woken thread will run immediately upon being woken "},
:properties {:color "yellow"}}
{:id #uuid "64354db0-8c74-4c14-b063-d26378a10555",
:page 386,
:position {:bounding {:x1 281.8214340209961,
:y1 997.6697082519531,
:x2 477.6873245239258,
:y2 1021.0982971191406,
:width 864,
:height 1296},
:rects ({:x1 286.6964340209961,
:y1 997.6697082519531,
:x2 477.6873245239258,
:y2 1021.0982971191406,
:width 864,
:height 1296}
{:x1 281.8214340209961,
:y1 999.3304138183594,
:x2 477.6873245239258,
:y2 1017.2590026855469,
:width 864,
:height 1296}),
:page 386},
:content {:text " always use while loops"},
:properties {:color "yellow"}}
{:id #uuid "64354f54-b26c-48dc-a328-4ae355b680f3",
:page 390,
:position {:bounding {:x1 593.6900482177734,
:y1 484.1875305175781,
:x2 652.7586212158203,
:y2 501.9018249511719,
:width 864,
:height 1296},
:rects ({:x1 593.6900482177734,
:y1 484.1875305175781,
:x2 652.7586212158203,
:y2 501.9018249511719,
:width 864,
:height 1296}),
:page 390},
:content {:text "albeit "},
:properties {:color "green"}}
{:id #uuid "64355441-5a1b-4015-baa1-65917526079c",
:page 391,
:position {:bounding {:x1 494.5921096801758,
:y1 1057.4464721679688,
:x2 649.2800369262695,
:y2 1080.8750610351562,
:width 864,
:height 1296},
:rects ({:x1 494.61609649658203,
:y1 1057.4464721679688,
:x2 649.2800369262695,
:y2 1080.8750610351562,
:width 864,
:height 1296}
{:x1 494.5921096801758,
:y1 1059.1072082519531,
:x2 649.2800369262695,
:y2 1076.8214721679688,
:width 864,
:height 1296}),
:page 391},
:content {:text "covering condition"},
:properties {:color "yellow"}}
{:id #uuid "643554f4-75a7-48fa-9366-87058ee723fb",
:page 390,
:position {:bounding {:x1 171.89286422729492,
:y1 317.60716247558594,
:x2 249.12459182739258,
:y2 341.0357208251953,
:width 864,
:height 1296},
:rects ({:x1 171.89286422729492,
:y1 317.60716247558594,
:x2 249.12459182739258,
:y2 341.0357208251953,
:width 864,
:height 1296}),
:page 390},
:content {:text "spurious "},
:properties {:color "green"}}
{:id #uuid "64355502-f41f-40dd-b71f-e0abdbc76716",
:page 390,
:position {:bounding {:x1 171.89286422729492,
:y1 317.60716247558594,
:x2 322.3585624694824,
:y2 341.0357208251953,
:width 864,
:height 1296},
:rects ({:x1 171.89286422729492,
:y1 317.60716247558594,
:x2 322.3585624694824,
:y2 341.0357208251953,
:width 864,
:height 1296}),
:page 390},
:content {:text "spurious wakeups"},
:properties {:color "yellow"}}],
:extra {:page 361}}
:extra {:page 396}}

View File

@ -370,7 +370,7 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
hl-page:: 357
hl-color:: yellow
id:: 64352221-d590-4371-a5f0-29e9cfa75ccb
- efficacy
- efficacy 功效,效力
ls-type:: annotation
hl-page:: 341
hl-color:: green
@ -380,23 +380,207 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
hl-page:: 347
hl-color:: green
id:: 6434f523-44b7-40ab-8fea-528969c5acfd
- delve
- delve 钻研;探究;挖
ls-type:: annotation
hl-page:: 349
hl-color:: green
id:: 6434fb8c-2b3b-4d80-83fb-3b34da4dcd28
- brag
- brag 吹嘘;自吹自擂
ls-type:: annotation
hl-page:: 351
hl-color:: green
id:: 643501c1-f11b-4e85-8125-d2a5a31f69b0
- intergalactic
ls-type:: annotation
hl-page:: 355
hl-color:: green
id:: 643509b5-12a0-4ed9-8a96-f70b3fc0e373
- scourge
- 鞭打;鞭笞;折磨;使受苦难
- Lock-based Concurrent Data Structures
ls-type:: annotation
hl-page:: 355
hl-page:: 361
hl-color:: yellow
id:: 643525b0-e245-489b-877d-a2a1d63e7ea6
- **Concurrent Counters**
hl-page:: 361
ls-type:: annotation
id:: 643525e5-fb85-48d4-905a-2a88b9ac0b0d
hl-color:: yellow
collapsed:: true
- **Counter with lock**
- Wrap the all the operations with a single lock.
- Performance is bad due to lock contention and it gets worse when the number of threads increases.
- **perfect scaling**: the increase in thread number doesn't harm the performance
hl-page:: 363
ls-type:: annotation
id:: 64352751-d9bd-4d5e-a8ba-cd18f86b1a15
hl-color:: yellow
- **approximate counter**
hl-page:: 363
ls-type:: annotation
id:: 64352794-d7c8-42f9-8321-f874967cebf2
hl-color:: yellow
- represent a single logical counter via ==numerous local physical counters==(one per CPU core), as well as ==a single global counter==. Each actual counter has a ==lock==.
- To add the counter, acquire the ==local lock== and increase it, thus avoiding contention.
- To read the counter, acquire the ==global lock== and read.
- To keep the global counter up to date, the local values are periodically transferred to the global counter and reset, which requires ==global lock and local lock==. A threshold `S` determines how often this transfer happens, tuning the trade-off between scalability and precision.
- **Concurrent Linked Lists**
ls-type:: annotation
hl-page:: 367
hl-color:: yellow
id:: 643530d8-9d09-4c8a-9e92-47dfe814ef50
collapsed:: true
- Again, the simplest way to implement this is to wrap all operations on the list with a single lock.
- Assuming the `malloc` is ==thread-safe==, we can improve the code a little by narrowing critical section: only operations on global structure need to be locked.
- **hand-over-hand locking**: a lock per node.
hl-page:: 369
ls-type:: annotation
id:: 64353237-4b74-4148-b7c1-5854d83a18c7
hl-color:: yellow
- When traversing the list, the code first grabs the next node's lock and then releases the current node's lock.
- In practice, it ==doesn't work== due to prohibitive overhead
- **Concurrent Queues**
ls-type:: annotation
hl-page:: 370
hl-color:: yellow
id:: 64353353-9de2-421b-967d-dc80a597eecd
- Two locks, head and tail, for `enqueue` and `dequeue` operation.
- Add a dummy node to separate head and tail operation. Without this, `dequeue` operation needs to acquire both locks in case the queue is empty.
- **Concurrent Hash Table**
hl-page:: 372
ls-type:: annotation
id:: 6435360d-c176-494a-9d61-b1fd0107a9bd
hl-color:: yellow
- instead of having a single lock for the entire structure, it uses a lock per hash bucket
ls-type:: annotation
hl-page:: 372
hl-color:: yellow
id:: 6435363d-c697-42a6-bfd0-8a2332cef394
- ubiquitous 似乎无所不在的;十分普遍的
ls-type:: annotation
hl-page:: 372
hl-color:: green
id:: 6435365a-b5d6-46fc-a9a1-25b0d23aa529
- humble 谦逊;低声下气;虚心;贬低
ls-type:: annotation
hl-page:: 373
hl-color:: green
id:: 6435367f-dd9e-449d-b0e4-3d8c9e14f6c2
- sloppy 马虎的,草率的;(衣服)宽松肥大的;太稀的,不够稠的;
hl-page:: 376
ls-type:: annotation
id:: 643536c8-fc05-4bbe-8d1d-0f4f6d1c4fee
hl-color:: green
- gross 总的,毛的;严重的,极端的;粗鲁的;臃肿的;粗略的;
hl-page:: 378
ls-type:: annotation
id:: 643537d3-7d01-442b-b47e-59433c2aa6db
hl-color:: green
- **condition variable**
hl-page:: 378
ls-type:: annotation
id:: 643537ff-1028-4725-8d7a-c0338cc946d3
hl-color:: yellow
- A ==condition variable== is an explicit queue that threads can put themselves on when some state of execution(condition) is not as desired (by *waiting on the condition*); some other thread, when it changes said state, can then wake one (or more) of those waiting threads and thus allow them to continue (by *signaling*).
hl-page:: 378
ls-type:: annotation
id:: 64353882-7697-4c16-8e53-c8f59ea256c1
hl-color:: yellow
- Operations
- `wait()` put the caller to sleep. `pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)`
hl-page:: 378
ls-type:: annotation
id:: 643538d5-9ea3-4399-9fa2-d75fdf0e1dd4
hl-color:: yellow
- `signal()` wake up a sleeping thread waiting on this condition. `pthread_cond_signal(pthread_cond_t *c);`
hl-page:: 379
ls-type:: annotation
id:: 643538de-cc40-4dd2-8f03-9492004f209b
hl-color:: yellow
- The `wait()` also takes a mutex as a parameter; it assumes that this mutex is locked when `wait()` is called. The responsibility of `wait()` is to ==release the lock and put the calling thread to sleep== (atomically); when the thread wakes up, it must ==re-acquire the lock before returning== to the caller. The design is helpful to avoid some race conditions when trying to sleep.
- use a while loop instead of just an if statement when deciding whether to wait on the condition.
ls-type:: annotation
hl-page:: 380
hl-color:: yellow
id:: 643547c5-1613-49e9-899e-0e86f59a1462
- stem
ls-type:: annotation
hl-page:: 379
hl-color:: green
id:: 64353eb8-8ed8-4680-a3c0-91608b429408
- **producer/consumer problem**
hl-page:: 382
ls-type:: annotation
id:: 64354974-adea-4b20-90f4-a12ebe1e4d5b
hl-color:: yellow
- **Mesa semantics**: Signaling a thread only wakes them up; it is thus a hint that the state of the world has ==changed==, but there is ==no guarantee== that when the woken thread runs, the state will ==still be as desired==. (Another guy may run before the thread and change the state again)
hl-page:: 385
ls-type:: annotation
id:: 64354cc4-14c5-408d-b879-7d4d011b2b5c
hl-color:: yellow
- So, always use while loops. While loops make sure the thread wake up in the desired state of world, which tackles the ((64355502-f41f-40dd-b71f-e0abdbc76716)) and provides support for ((64355441-5a1b-4015-baa1-65917526079c))
hl-page:: 386
ls-type:: annotation
id:: 64354db0-8c74-4c14-b063-d26378a10555
hl-color:: yellow
- **Hoare semantics**: provides a stronger guarantee that the woken thread will run immediately upon being woken
hl-page:: 386
ls-type:: annotation
id:: 64354d46-4286-44fd-9e82-2ba562a50f25
hl-color:: yellow
- Incorrect Solution: single condition variable. The problem arises from the ==undirected wakeup operation==: God knows which thread is to be woken up.
- Envision multiple consumers and one producer:
1. producer `P1` increases count to 1, signals the CV and sleeps
2. consumer `C1` is awaken, reduces count to 0, signals the CV and sleeps
3. another consumer `C2` is woken up ==by accident==, finds out count is 0, sleeps
4. In this case, they all sleep and thus nobody will signal any of them
- If in step 3, the producer `P1` is woken up, everything is fine. Obviously, one solution is to ==exert control over which thread is to be woken up==. Well, wake up all threads may also solve this problem, see ((64355441-5a1b-4015-baa1-65917526079c)).
- Correct solution: 2 condition variable.
- Producer threads wait on the condition `empty`, and signals `fill`. Conversely, consumer threads wait on `fill` and signal `empty`.
- Code
```C
cond_t empty, fill;
mutex_t mutex;
void *producer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
Pthread_mutex_lock(&mutex);
while (count == MAX)
Pthread_cond_wait(&empty, &mutex);
put(i);
Pthread_cond_signal(&fill);
Pthread_mutex_unlock(&mutex);
}
}
void *consumer(void *arg) {
int i;
for (i = 0; i < loops; i++) {
Pthread_mutex_lock(&mutex);
while (count == 0)
Pthread_cond_wait(&fill, &mutex);
int tmp = get();
Pthread_cond_signal(&empty);
Pthread_mutex_unlock(&mutex);
printf("%d\n", tmp);
}
}
```
- **spurious wakeups**
hl-page:: 390
ls-type:: annotation
id:: 64355502-f41f-40dd-b71f-e0abdbc76716
hl-color:: yellow
- In some thread packages, due to details of the implementation, it is possible that two threads get woken up though just a single signal has taken place.
- **covering condition**
hl-page:: 391
ls-type:: annotation
id:: 64355441-5a1b-4015-baa1-65917526079c
hl-color:: yellow
- covers all the cases where a thread needs to wake up, those unneeded simply wake up, re-check condition and go back to sleep
- `pthread_cond_broadcast()` wakes up all waiting threads
- albeit 尽管;虽然
ls-type:: annotation
hl-page:: 390
hl-color:: green
id:: 64354f54-b26c-48dc-a328-4ae355b680f3
- spurious 虚假的;伪造的;建立在错误的观念(或思想方法)之上的;谬误的
hl-page:: 390
ls-type:: annotation
id:: 643554f4-75a7-48fa-9366-87058ee723fb
hl-color:: green
id:: 643509ba-662e-4d0a-906a-fd0987e24574