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 25
25
习题完成情况:
26
26
- 章节一: 43/46
27
27
- 章节二: 88/97
28
- - 章节三: 46 /82
28
+ - 章节三: 47 /82
29
29
- 章节四: TODO
30
30
- 章节五: TODO
31
31
* 运行
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