File tree Expand file tree Collapse file tree 3 files changed +90
-1
lines changed Expand file tree Collapse file tree 3 files changed +90
-1
lines changed Original file line number Diff line number Diff line change 2525 习题完成情况:
2626 - 章节一: 43/46
2727 - 章节二: 88/97
28- - 章节三: 46 /82
28+ - 章节三: 47 /82
2929 - 章节四: TODO
3030 - 章节五: TODO
3131* 运行
Original file line number Diff line number Diff line change 1+ #lang racket
2+
3+ (require "mutex.rkt " )
4+
5+ (define (make-semaphore n)
6+ (let ((count n)
7+ (mutex (make-mutex)))
8+ (define (acquire)
9+ (let loop ()
10+ (mutex 'acquire )
11+ (if (> count 0 )
12+ (begin
13+ (set! count (- count 1 ))
14+ (mutex 'release ))
15+ (begin
16+ (mutex 'release )
17+ (sleep 0.01 )
18+ (loop)))))
19+
20+ (define (release)
21+ (mutex 'acquire )
22+ (set (count (+ count 1 )))
23+ (mutex 'release ))
24+
25+ (lambda (m)
26+ (cond ((eq? m 'acquire ) acquire)
27+ ((eq? m 'release ) release)
28+ (else (error "Unknown operation " m))))))
29+
30+ (module+ test
31+ (require rackunit)
32+
33+ (test-case "Basic semaphore operations "
34+ (define sem (make-semaphore 2 ))
35+
36+ (check-not-exn (lambda () (sem 'acquire )))
37+ (check-not-exn (lambda () (sem 'acquire )))
38+
39+ (check-not-exn (lambda () (sem 'release ))))
40+
41+ (test-case "Threading test "
42+ (define sem (make-semaphore 1 ))
43+ (define results '() )
44+ (define result-mutex (make-mutex))
45+
46+ (define (add-result x)
47+ (result-mutex 'acquire )
48+ (set! results (cons x results))
49+ (result-mutex 'release ))
50+
51+ (sem 'acquire )
52+
53+ (thread (lambda ()
54+ (sleep 0.05 )
55+ (add-result 'thread-started )
56+ (sem 'acquire )
57+ (add-result 'thread-acquired )
58+ (sem 'release )))
59+
60+ (add-result 'main-holding )
61+ (add-result 'main-releasing )
62+ (sem 'release )
63+
64+ ;; Give thread time to complete
65+ (sleep 0.2 )
66+ (check-equal? (car results) 'thread-acquired )
67+ (check-equal? (car (cdr results)) 'thread-started )
68+ )
69+ )
Original file line number Diff line number Diff line change 1+ #lang racket
2+ (define (test-and-set! cell)
3+ ;; box-cas! is atomic operation
4+ (not (box-cas! cell #f #t )))
5+
6+ (define (make-mutex)
7+ (let ((cell (box #f )))
8+ (define (the-mutex m)
9+ (cond ((eq? m 'acquire )
10+ (when (test-and-set! cell)
11+ ;; retry
12+ (the-mutex 'acquire )))
13+ ((eq? m 'release )
14+ (clear! cell))))
15+ the-mutex))
16+
17+ (define (clear! cell)
18+ (box-cas! cell #t #f ))
19+
20+ (provide make-mutex)
You can’t perform that action at this time.
0 commit comments