OSTEP Chapter 31

This commit is contained in:
ridethepig 2023-04-12 01:01:51 +08:00
parent 6994bb7a34
commit 6172227724
4 changed files with 704 additions and 4 deletions

View File

@ -1812,5 +1812,384 @@
:height 1296}),
:page 390},
:content {:text "spurious wakeups"},
:properties {:color "yellow"}}
{:id #uuid "64356d96-cce8-48ad-80f1-e3e02a1a4684",
:page 396,
:position {:bounding {:x1 131.578125,
:y1 921.546875,
:x2 249.6654510498047,
:y2 945.546875,
:width 979.1999999999999,
:height 1468.8},
:rects ({:x1 131.578125,
:y1 921.546875,
:x2 249.6654510498047,
:y2 945.546875,
:width 979.1999999999999,
:height 1468.8}),
:page 396},
:content {:text "Semaphores"},
:properties {:color "yellow"}}
{:id #uuid "64356dba-48b4-49b8-8182-c962f12f03a5",
:page 396,
:position {:bounding {:x1 0,
:y1 301,
:x2 784.2239990234375,
:y2 1009.59375,
:width 979.1999999999999,
:height 1468.8},
:rects ({:x1 0,
:y1 301,
:x2 0,
:y2 323,
:width 979.1999999999999,
:height 1468.8}
{:x1 158.6875,
:y1 967,
:x2 784.2239990234375,
:y2 987,
:width 979.1999999999999,
:height 1468.8}
{:x1 131.578125,
:y1 989.59375,
:x2 290.9900207519531,
:y2 1009.59375,
:width 979.1999999999999,
:height 1468.8}),
:page 396},
:content {:text "A semaphore is an object with an integer value that we can manipulate with two routines;"},
:properties {:color "yellow"}}
{:id #uuid "64357404-d348-42b3-96a3-ba28575baa66",
:page 397,
:position {:bounding {:x1 402.39794921875,
:y1 611.3125,
:x2 466.92041015625,
:y2 630.3125,
:width 921.6,
:height 1382.4},
:rects ({:x1 402.39794921875,
:y1 611.3125,
:x2 466.92041015625,
:y2 630.3125,
:width 921.6,
:height 1382.4}),
:page 397},
:content {:text "salient "},
:properties {:color "green"}}
{:id #uuid "6435744b-a300-40ad-ba91-157666d8cd2a",
:page 397,
:position {:bounding {:x1 359.15777587890625,
:y1 1154.46875,
:x2 725.4879150390625,
:y2 1179.46875,
:width 921.6,
:height 1382.4},
:rects ({:x1 359.171875,
:y1 1154.46875,
:x2 725.4879150390625,
:y2 1179.46875,
:width 921.6,
:height 1382.4}
{:x1 359.15777587890625,
:y1 1156.1875,
:x2 359.16748046875,
:y2 1175.1875,
:width 921.6,
:height 1382.4}),
:page 397},
:content {:text "Semaphore: Definitions Of Wait And Post"},
:properties {:color "yellow"}}
{:id #uuid "64357512-e25b-4226-961a-caec367fc8a3",
:page 397,
:position {:bounding {:x1 0,
:y1 477,
:x2 797.5911254882812,
:y2 864.109375,
:width 921.6,
:height 1382.4},
:rects ({:x1 0,
:y1 477,
:x2 0,
:y2 499,
:width 921.6,
:height 1382.4}
{:x1 208.84375,
:y1 823.859375,
:x2 797.5911254882812,
:y2 842.859375,
:width 921.6,
:height 1382.4}
{:x1 183.359375,
:y1 845.109375,
:x2 379.579833984375,
:y2 864.109375,
:width 921.6,
:height 1382.4}),
:page 397},
:content {:text "Third, the value of the semaphore, when negative, is equal to the number of waiting threads "},
:properties {:color "yellow"}}
{:id #uuid "6435753a-65b5-4e46-82bc-54c11c1cd533",
:page 398,
:position {:bounding {:x1 123.828125,
:y1 461.921875,
:x2 404.9288024902344,
:y2 484.921875,
:width 921.6,
:height 1382.4},
:rects ({:x1 123.828125,
:y1 461.921875,
:x2 404.9288024902344,
:y2 484.921875,
:width 921.6,
:height 1382.4}),
:page 398},
:content {:text "Binary Semaphores (Locks)"},
:properties {:color "yellow"}}
{:id #uuid "64357930-2d96-4867-bc3d-2fe89990ce5f",
:page 399,
:position {:bounding {:x1 183.359375,
:y1 1122.015625,
:x2 450.3201599121094,
:y2 1145.015625,
:width 921.6,
:height 1382.4},
:rects ({:x1 183.359375,
:y1 1122.015625,
:x2 450.3201599121094,
:y2 1145.015625,
:width 921.6,
:height 1382.4}),
:page 399},
:content {:text "Semaphores For Ordering"},
:properties {:color "yellow"}}
{:id #uuid "64357c6d-381e-492e-b901-095454f5315e",
:page 401,
:position {:bounding {:x1 183.33059692382812,
:y1 1062.84375,
:x2 721.8597412109375,
:y2 1085.84375,
:width 921.6,
:height 1382.4},
:rects ({:x1 183.33059692382812,
:y1 1062.84375,
:x2 721.8597412109375,
:y2 1085.84375,
:width 921.6,
:height 1382.4}),
:page 401},
:content {:text "The Producer/Consumer (Bounded Buffer) Problem"},
:properties {:color "yellow"}}
{:id #uuid "643583b4-26b1-4cbf-801c-11ed6e63976e",
:page 406,
:position {:bounding {:x1 123.828125,
:y1 331.78125,
:x2 335.4051513671875,
:y2 354.78125,
:width 921.6,
:height 1382.4},
:rects ({:x1 123.828125,
:y1 331.78125,
:x2 335.4051513671875,
:y2 354.78125,
:width 921.6,
:height 1382.4}),
:page 406},
:content {:text "Reader-Writer Locks"},
:properties {:color "yellow"}}
{:id #uuid "64358755-1fae-4ea2-93a3-8c9d3d3e11c3",
:page 411,
:position {:bounding {:x1 726.3629150390625,
:y1 422.703125,
:x2 761.9802856445312,
:y2 441.703125,
:width 921.6,
:height 1382.4},
:rects ({:x1 726.3629150390625,
:y1 422.703125,
:x2 761.9802856445312,
:y2 441.703125,
:width 921.6,
:height 1382.4}),
:page 411},
:content {:text " bog"},
:properties {:color "green"}}
{:id #uuid "64358758-cb9c-4e8d-aaa4-f8e50457db88",
:page 411,
:position {:bounding {:x1 259.0669860839844,
:y1 334.59375,
:x2 367.23944091796875,
:y2 357.59375,
:width 921.6,
:height 1382.4},
:rects ({:x1 259.0669860839844,
:y1 334.59375,
:x2 367.23944091796875,
:y2 357.59375,
:width 921.6,
:height 1382.4}),
:page 411},
:content {:text "Throttling"},
:properties {:color "green"}}
{:id #uuid "643587a7-ade4-4f09-be50-aea233ff02c0",
:page 408,
:position {:bounding {:x1 123.81153106689453,
:y1 539.671875,
:x2 380.1902160644531,
:y2 562.671875,
:width 921.6,
:height 1382.4},
:rects ({:x1 123.81153106689453,
:y1 539.671875,
:x2 380.1902160644531,
:y2 562.671875,
:width 921.6,
:height 1382.4}),
:page 408},
:content {:text "The Dining Philosophers"},
:properties {:color "yellow"}}
{:id #uuid "64358802-3b22-46ed-a0e2-71cc9df69a7b",
:page 408,
:position {:bounding {:x1 513.1211547851562,
:y1 882.953125,
:x2 556.3884887695312,
:y2 901.953125,
:width 921.6,
:height 1382.4},
:rects ({:x1 513.1211547851562,
:y1 882.953125,
:x2 556.3884887695312,
:y2 901.953125,
:width 921.6,
:height 1382.4}),
:page 408},
:content {:text "ensue"},
:properties {:color "green"}}
{:id #uuid "6435889f-1375-4b94-8630-b3d0d7bdfa56",
:page 408,
:position {:bounding {:x1 0,
:y1 381,
:x2 738.0819091796875,
:y2 901.953125,
:width 921.6,
:height 1382.4},
:rects ({:x1 0,
:y1 381,
:x2 0,
:y2 403,
:width 921.6,
:height 1382.4}
{:x1 0,
:y1 397,
:x2 0,
:y2 419,
:width 921.6,
:height 1382.4}
{:x1 0,
:y1 413,
:x2 0,
:y2 435,
:width 921.6,
:height 1382.4}
{:x1 0,
:y1 429,
:x2 0,
:y2 451,
:width 921.6,
:height 1382.4}
{:x1 0,
:y1 445,
:x2 0,
:y2 467,
:width 921.6,
:height 1382.4}
{:x1 174.31170654296875,
:y1 776.6875,
:x2 738.0610961914062,
:y2 795.6875,
:width 921.6,
:height 1382.4}
{:x1 123.828125,
:y1 797.9375,
:x2 738.0778198242188,
:y2 817.0625,
:width 921.6,
:height 1382.4}
{:x1 123.828125,
:y1 819.1875,
:x2 738.0721435546875,
:y2 838.3125,
:width 921.6,
:height 1382.4}
{:x1 123.828125,
:y1 840.4375,
:x2 738.0819091796875,
:y2 859.5625,
:width 921.6,
:height 1382.4}
{:x1 123.828125,
:y1 861.703125,
:x2 738.0709838867188,
:y2 880.828125,
:width 921.6,
:height 1382.4}
{:x1 123.828125,
:y1 882.953125,
:x2 175.7489471435547,
:y2 901.953125,
:width 921.6,
:height 1382.4}),
:page 408},
:content {:text "here are five “philosophers” sitting around a table. Between each pair of philosophers is a single fork (and thus, five total). The philosophers each have times where they think, and dont need any forks, and times where they eat. In order to eat, a philosopher needs two forks, both the one on their left and the one on their right. The contention for these forks,"},
:properties {:color "yellow"}}
{:id #uuid "643589a6-31e6-4603-9259-999e9c8860f7",
:page 411,
:position {:bounding {:x1 269.5417785644531,
:y1 887.1875,
:x2 515.8197631835938,
:y2 910.1875,
:width 921.6,
:height 1382.4},
:rects ({:x1 269.5417785644531,
:y1 887.1875,
:x2 515.8197631835938,
:y2 910.1875,
:width 921.6,
:height 1382.4}),
:page 411},
:content {:text "Implement Semaphores"},
:properties {:color "yellow"}}
{:id #uuid "64358b0c-e441-4d0a-852d-ecfde369306c",
:page 410,
:position {:bounding {:x1 627.167236328125,
:y1 1150.953125,
:x2 738.0892333984375,
:y2 1169.953125,
:width 921.6,
:height 1382.4},
:rects ({:x1 627.167236328125,
:y1 1150.953125,
:x2 738.0892333984375,
:y2 1169.953125,
:width 921.6,
:height 1382.4}),
:page 410},
:content {:text "ramifications"},
:properties {:color "green"}}
{:id #uuid "64358de1-f418-44fd-8a77-bc0faa368059",
:page 412,
:position {:bounding {:x1 274.109375,
:y1 773.328125,
:x2 701.076904296875,
:y2 798.328125,
:width 921.6,
:height 1382.4},
:rects ({:x1 274.109375,
:y1 773.328125,
:x2 701.076904296875,
:y2 798.328125,
:width 921.6,
:height 1382.4}),
:page 412},
:content {:text "Implementing Zemaphores With Locks And CVs"},
:properties {:color "yellow"}}],
:extra {:page 396}}
:extra {:page 416}}

1
journals/2023_04_11.md Normal file
View File

@ -0,0 +1 @@
- 大概了解了一下体系结构方向的东西

View File

@ -0,0 +1,133 @@
file:: [ostep_1681115599584_0.pdf](../assets/ostep_1681115599584_0.pdf)
file-path:: ../assets/ostep_1681115599584_0.pdf
- # Part II
- thread
ls-type:: annotation
hl-page:: 311
hl-color:: yellow
id:: 6433ca28-1bdf-433d-8ed9-0d54bf5ba940
- share the same address space and thus can access the same data
- context switch: the address space remains the same
hl-page:: 311
ls-type:: annotation
id:: 6433cb70-d168-4863-8268-1e969df6ce06
hl-color:: yellow
- thread control blocks
ls-type:: annotation
hl-page:: 311
hl-color:: yellow
id:: 6433cb56-fbef-46da-83c2-13fa2dba2967
- thread-local storage: one stack per thread in the address space
hl-page:: 312
ls-type:: annotation
id:: 6433cba2-61bd-4549-a29f-2ad85b3e30cd
hl-color:: yellow
- Why thread?
- possible speedup through parallelization
- enable overlap of IO in a single program
- Though these could be done through multi-processing, threading makes share data easier
- KEY CONCURRENCY TERMS
ls-type:: annotation
hl-page:: 323
hl-color:: yellow
id:: 6433eabf-48d6-4776-b66f-a5f7804d1ddc
- **indeterminate**: the results depend on the timing execution of the code.
- race condition
ls-type:: annotation
hl-page:: 320
hl-color:: yellow
id:: 6433e4cc-69e4-4057-8cc6-1766240d82f4
- A **critical section** is a piece of code that accesses a shared variable (or resource) and must not be concurrently executed by more than one thread.
hl-page:: 320
ls-type:: annotation
id:: 6433e52b-1f38-4f7c-b168-0aed624f9bdf
hl-color:: yellow
- **mutual exclusion**: This property guarantees that if one thread is executing within the *critical section*, the others will be prevented from doing so.
hl-page:: 320
ls-type:: annotation
id:: 6433e566-e6ef-45b3-84b1-eba981be914a
hl-color:: yellow
- Atomicity: *as a unit*, or, *all or none*
hl-page:: 321
ls-type:: annotation
id:: 6433e6a1-407c-4936-b184-dee868ef4107
hl-color:: yellow
- synchronization primitives
ls-type:: annotation
hl-page:: 322
hl-color:: yellow
id:: 6433e729-7043-453b-8d60-6e6c41560543
- sane 精神健全的;神志正常的;明智的;理智的
ls-type:: annotation
hl-page:: 322
hl-color:: green
id:: 6433e6e7-d995-4b69-96b3-261b79f94c1d
- Thread API
hl-page:: 327
ls-type:: annotation
id:: 6433f35b-403b-4b25-b9f9-076e9e34777e
hl-color:: yellow
- `pthread_create` `pthread_join` `pthread_mutex_lock` `pthread_cond_*`
- Locks
ls-type:: annotation
hl-page:: 339
hl-color:: yellow
id:: 6433f45b-0345-4790-8379-3d1a94e57ef5
- A lock is just a variable
hl-page:: 339
ls-type:: annotation
id:: 6433f4ba-f2e4-4743-a536-e2b7747433b7
hl-color:: yellow
- **lock variable**: some type of variable, which holds the *state* of the lock(and maybe additional data such as its holder or a queue for acquisition)
- **lock state**: available (or unlocked or free); acquired (or locked or held)
- **lock routines**:
- `lock()` tries to acquire the lock. If no other thread holds the lock, the thread will acquire the lock and enter the critical section(become the owner of the lock). Otherwise, it will not return while the lock is held by another thread.
- `unlock()` : The owner of the lock calls `unlock()`, then it is *available* again. If there are waiting threads, one of them will (eventually) notice (or be informed of) this change of the lock's state, acquire the lock, and enter the critical section.
- Locks help transform the chaos that is traditional OS scheduling into a more controlled activity
hl-page:: 340
ls-type:: annotation
id:: 6433f5e6-bc06-42a9-866e-e9a3053f528f
hl-color:: yellow
- Controlling Interrupts
ls-type:: annotation
hl-page:: 342
hl-color:: yellow
id:: 6433fbfd-a1bf-4fd9-a54d-e15189c77b15
- For *single-processor* systems, **disable interrupts** for critical sections.
- Problems
- disable interrupts is privileged. In the worst case, the OS may never regain control when the interrupt isn't going to be enabled.
- does NOT work on multi-processor systems, each CPU has its own interrupt state
- importance interrupts may get lost
- inefficient
- Just Using Loads/Stores(Fail)
hl-page:: 343
ls-type:: annotation
id:: 6433fe7e-2221-41ee-ad6b-7deaa4459aa5
hl-color:: yellow
- use a simple variable (flag) to indicate whether some thread has possession of a lock
hl-page:: 343
ls-type:: annotation
id:: 6433ff4a-856d-4e4b-af30-6cb600aefeb5
hl-color:: yellow
- On acquisition, load, test the flag. If free, set the flag; If not free, spin-wait(loop load and test).
- On releasing, clear the flag.
- Problem
- When interrupted between load and test, *mutual exclusion* is broken.
- Low efficiency because of spin-waiting.
- Spin Locks with Test-And-Set
ls-type:: annotation
hl-page:: 344
hl-color:: yellow
id:: 64340154-807c-4a7a-b783-045d5d6d3927
- **test-and-set (or atomic exchange) instruction**
hl-page:: 344
ls-type:: annotation
id:: 643401e0-fcec-41d3-9898-d5c4175ac464
hl-color:: yellow
-
- efficacy
ls-type:: annotation
hl-page:: 341
hl-color:: green
id:: 6433fb69-1425-46b4-996f-f91da5d3e8d0

View File

@ -499,11 +499,12 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
hl-page:: 380
hl-color:: yellow
id:: 643547c5-1613-49e9-899e-0e86f59a1462
- stem
ls-type:: annotation
- stem (花草的)茎;(花或叶的)梗,柄;阻止;封堵;遏止;
hl-page:: 379
hl-color:: green
ls-type:: annotation
id:: 64353eb8-8ed8-4680-a3c0-91608b429408
hl-color:: green
- **stem from sth ** 是…的结果;起源于;根源是
- **producer/consumer problem**
hl-page:: 382
ls-type:: annotation
@ -583,4 +584,190 @@ file-path:: ../assets/ostep_1681115599584_0.pdf
hl-page:: 390
ls-type:: annotation
id:: 643554f4-75a7-48fa-9366-87058ee723fb
hl-color:: green
- Semaphores
ls-type:: annotation
hl-page:: 396
hl-color:: yellow
id:: 64356d96-cce8-48ad-80f1-e3e02a1a4684
- A semaphore is an ==object with an integer value== that we can manipulate with two routines `sem_wait()` and `sem_post()`. The initial value determines its behavior, so we need to give it an initial value through `sem_init()`
hl-page:: 396
ls-type:: annotation
id:: 64356dba-48b4-49b8-8182-c962f12f03a5
hl-color:: yellow
- Semaphore: Definitions Of **Wait And Post**
ls-type:: annotation
hl-page:: 397
hl-color:: yellow
id:: 6435744b-a300-40ad-ba91-157666d8cd2a
collapsed:: true
- `sem_wait(sem_t *s)`: First decrement the value of the semaphore by one. Then wait if the value of semaphore is negative
- `sem_post(sem_t*s)`: First increment the value of the semaphore by one. If there is any thread waiting, wait up one of them
- The value of the semaphore, *when negative*, is equal to the ==number of waiting threads==
hl-page:: 397
ls-type:: annotation
id:: 64357512-e25b-4226-961a-caec367fc8a3
hl-color:: yellow
- **Binary Semaphores (Locks)**
ls-type:: annotation
hl-page:: 398
hl-color:: yellow
id:: 6435753a-65b5-4e46-82bc-54c11c1cd533
collapsed:: true
- Initialize semaphore to 1, indicating we only have one piece of resource (the critical section).
- Wrap the critical section with `sem_wait` and `sem_post`
- When the lock is acquired, the semaphore is 0. On another acquisition request, the value goes to -1, which makes the caller sleep. When the lock is free, the value is decreased to 0 on acquisition, which will not get stuck.
- **Semaphores For Ordering (Condition Variable, or Ordering Primitive)**
hl-page:: 399
ls-type:: annotation
id:: 64357930-2d96-4867-bc3d-2fe89990ce5f
hl-color:: yellow
collapsed:: true
- Initialize the semaphore to 0
- Consider the *join* operation. The parent calls `sem_wait`and the child calls `sem_post`. In either case, no matter which thread is scheduled first, the semaphore guarantees the desired result.
- **The Producer/Consumer (Bounded Buffer) Problem (Again)**
hl-page:: 401
ls-type:: annotation
id:: 64357c6d-381e-492e-b901-095454f5315e
hl-color:: yellow
collapsed:: true
- 2 semaphores `empty` and `full` for coordination between consumer and producer, and 1 semaphore for lock
- Initialize `empty <- MAX`, and `full <- 0`
- Consumer waits for `full` and posts `empty` and conversely, produce waits for `empty` and posts `full`
- Special case for `MAX=1`
- When only one slot is available in the buffer, we don't even need a lock! Actually, it is binary semaphore which not only controls the buffer entry but also works as a lock.
- Otherwise, there will be a ==data race== inside the `put/get` operation due to potential multi-thread access to these procedures (when `MAX > 1`, the `sem_wait(&empty)` may allow in more than one thread).
- Deadlock avoidance
- If the lock semaphore is the outmost semaphore, deadlock occurs (the thread may sleep in `sem_wait(&empty)` with `mutex` unrelease). Therefore, put the lock inside the `empty/full` semaphore pair.
- Implement
```C
int empty = MAX, full = 0, mutex = 1;
void *producer() {
for (int i = 0; i < loops; ++ i) {
sem_wait(&empty);
sem_wait(&mutex);
put(i);
sem_post(&mutex);
sem_post(&full);
}
}
void *consumer() {
for (int i = 0; i < loops; ++ i) {
sem_wait(&full);
sem_wait(&mutex);
int tmp = get();
sem_post(&mutex);
sem_post(&empty);
printf("%d\n", tmp);
}
}
```
- **Reader-Writer Locks**
ls-type:: annotation
hl-page:: 406
hl-color:: yellow
id:: 643583b4-26b1-4cbf-801c-11ed6e63976e
- Either allow ==multiple readers to read== concurrently, or allow ==only one writer to write==.
- Two sets of operation
- `rwlock_acquire/release_writelock()`: simply `wait/post` the `writelock`
- `rwlock_acquire/release_readlock()`: acquire `writelock` when the ==first reader acquires==, and release it when the ==last reader releases==
- Implement
```C
typedef struct _rwlock_t {
sem_t guard; // binary semaphore (basic lock)
sem_t writelock; // allow ONE writer/MANY readers
int readers; // #readers in critical section
} rwlock_t;
void rwlock_acquire_readlock(rwlock_t *rw) {
sem_wait(&rw->guard);
if (++rw->readers == 1) sem_wait(&rw->writelock);
sem_post(&rw->guard);
}
void rwlock_release_readlock(rwlock_t *rw) {
sem_wait(&rw->guard);
if (--rw->readers == 0) sem_post(&rw->writelock);
sem_post(&rw->guard);
}
void rwlock_acquire_writelock(rwlock_t *rw) { sem_wait(&rw->writelock); }
void rwlock_release_writelock(rwlock_t *rw) { sem_post(&rw->writelock); }
```
- Problem: More overhead; Unfairness, writer is much more likely to starve.
- To tackle the writer starvation problem, we may manually wake up the writers (if ever suspended) on read lock release. [Wiki](https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock)
- **The Dining Philosophers**
hl-page:: 408
ls-type:: annotation
id:: 643587a7-ade4-4f09-be50-aea233ff02c0
hl-color:: yellow
- Background setting
hl-page:: 408
ls-type:: annotation
id:: 6435889f-1375-4b94-8630-b3d0d7bdfa56
hl-color:: yellow
- 5 "philosophers" around a table.
Between each pair of philosophers is a single fork (and thus, 5 total).
The philosophers each have times where they think (dont need forks), and times where they eat.
In order to eat, a philosopher needs two forks (left and right).
The contention for these forks is our synchronization problem.
- Solution
- A semaphore per fork, and helper function `left/right(p)` which is the fork on philosopher `p`'s left/right.
- Deadlock: if each philosopher tries to grab the fork on their left first, there will be a deadlock. When all of them get their left-side forks, all of the forks are locked and no one could get their right-side fork.
- Non-deadlock: force one philosopher to try to grab the right-side fork first
- Implement
```C
void put_forks(int p) {
sem_post(&forks[left(p)]);
sem_post(&forks[right(p)]);
}
void get_forks(int p) {
if (p == 4) {
sem_wait(&forks[right(p)]);
sem_wait(&forks[left(p)]);
} else {
sem_wait(&forks[left(p)]);
sem_wait(&forks[right(p)]);
}
}
void philosopher() {
while (1) {
think();
get_forks(p);
eat();
put_forks(p);
}
}
```
- Implement Semaphores
ls-type:: annotation
hl-page:: 411
hl-color:: yellow
id:: 643589a6-31e6-4603-9259-999e9c8860f7
- Implementing Zemaphores With One Lock And One CV: the book authors provide us a simple implement for semaphore, though somewhat different from its definition.
hl-page:: 412
ls-type:: annotation
id:: 64358de1-f418-44fd-8a77-bc0faa368059
hl-color:: yellow
- salient 最重要的;显着的;突出的:
ls-type:: annotation
hl-page:: 397
hl-color:: green
id:: 64357404-d348-42b3-96a3-ba28575baa66
- ensue 跟着发生,接着发生;
ls-type:: annotation
hl-page:: 408
hl-color:: green
id:: 64358802-3b22-46ed-a0e2-71cc9df69a7b
- Throttle 节流阀;风门;喉咙;使窒息;使节流;
hl-page:: 411
ls-type:: annotation
id:: 64358758-cb9c-4e8d-aaa4-f8e50457db88
hl-color:: green
- bog 沼泽;泥塘;使陷于泥沼;使动弹不得
hl-page:: 411
ls-type:: annotation
id:: 64358755-1fae-4ea2-93a3-8c9d3d3e11c3
hl-color:: green
- ramification (众多复杂而又难以预料的)结果,后果
hl-page:: 410
ls-type:: annotation
id:: 64358b0c-e441-4d0a-852d-ecfde369306c
hl-color:: green