-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path3_47.rkt
52 lines (41 loc) · 2.82 KB
/
3_47.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#lang racket
#| Solution for exercise 3_47. |#
;; a. Реализация семафора в терминах мьютекса:
;; Для данной реализации, нам в сущности потребуется создать счётчик, который берет мьютекс перед началом своего изменения, и возвращает после.
(define (make-semaphore max)
(let ((counter max)
(mutex (make-mutex)))
(define (the-semaphore m)
(cond ((eq? m 'take-semaphore)
(mutex 'acquire)
(if (> counter 0)
(begin
(set! counter (- counter 1))
(mutex 'release))
(begin
(mutex 'release)
(take-semaphore 'take-semaphore))))
((eq? m 'release-semaphore)
(mutex 'acquire)
(set! counter (+ counter 1))
(mutex 'release))))
take-semaphore))
;; b. Реализация семафора в терминах атомарной операции set-and-test!
(define (make-semaphore n)
(let ((counter (list n)))
(define (the-semaphore m)
(cond ((eq? m 'take-semaphore)
(if (test-and-set! counter)
(the-semaphore 'take-semaphore)))
((eq? m 'release-semaphore)
(release counter))))
take-semaphore))
(define (test-and-set! counter)
(if (= (car counter) 0)
true
(begin
(set-car! counter (- (car counter) 1))
false)))
(define (release counter)
(set-car! counter (+ (car counter) 1)))
;; Данная реализация явно имеет проблему, связанную с тем что освободить семафор может тот кто его не брал, соответственно считчик может стать больше, чем он был при создание семафора. При этом проверять в процедуре release не превысил ли счётчик своё максимальное значение, не лучшая идея, так как это может привести к тому, что процедура которая действительно занимала светофор, не сможет его вернуть. Пока не знаю насколько значительна данная проблема, например если использовать семафор через процедуру, подобную make-serializer из текста главы, то проблемы с лишним возвратом семафора быть не должно, так как данная процедура изначально может возвращать семафор только после того как сама заняла его.