1
+ use std:: sync:: { mpsc:: channel, Arc } ;
2
+ use std:: thread;
3
+
4
+ use parking_lot:: RwLock ;
5
+ use parking_lot:: { FairMutex , Mutex , Once , ReentrantMutex } ;
6
+
7
+ pub fn mutex_example ( ) {
8
+ const N : usize = 10 ;
9
+
10
+ let data = Arc :: new ( Mutex :: new ( 0 ) ) ;
11
+ let data2 = & data. clone ( ) ;
12
+
13
+ let ( tx, rx) = channel ( ) ;
14
+ for _ in 0 ..10 {
15
+ let ( data, tx) = ( Arc :: clone ( & data) , tx. clone ( ) ) ;
16
+ thread:: spawn ( move || {
17
+ // The shared state can only be accessed once the lock is held.
18
+ // Our non-atomic increment is safe because we're the only thread
19
+ // which can access the shared state when the lock is held.
20
+ let mut data = data. lock ( ) ;
21
+ * data += 1 ;
22
+ if * data == N {
23
+ tx. send ( ( ) ) . unwrap ( ) ;
24
+ }
25
+ // the lock is unlocked here when `data` goes out of scope.
26
+ } ) ;
27
+ }
28
+
29
+ rx. recv ( ) . unwrap ( ) ;
30
+
31
+ println ! ( "mutex_example: {}" , data2. lock( ) ) ;
32
+ }
33
+
34
+ pub fn mutex_example2 ( ) {
35
+ const N : usize = 10 ;
36
+
37
+ let mutex = Arc :: new ( Mutex :: new ( ( ) ) ) ;
38
+
39
+ let handles: Vec < _ > = ( 0 ..N )
40
+ . map ( |i| {
41
+ let mutex = Arc :: clone ( & mutex) ;
42
+ thread:: spawn ( move || {
43
+ let _lock = mutex. lock ( ) ;
44
+ println ! ( "thread {} done" , i) ;
45
+ } )
46
+ } )
47
+ . collect ( ) ;
48
+
49
+ for handle in handles {
50
+ handle. join ( ) . unwrap ( ) ;
51
+ }
52
+
53
+ println ! ( "mutex_example2: done" ) ;
54
+ }
55
+
56
+ pub fn fairmutex_example ( ) {
57
+ const N : usize = 10 ;
58
+
59
+ let data = Arc :: new ( FairMutex :: new ( 0 ) ) ;
60
+
61
+ let ( tx, rx) = channel ( ) ;
62
+ for _ in 0 ..10 {
63
+ let ( data, tx) = ( Arc :: clone ( & data) , tx. clone ( ) ) ;
64
+ thread:: spawn ( move || {
65
+ // The shared state can only be accessed once the lock is held.
66
+ // Our non-atomic increment is safe because we're the only thread
67
+ // which can access the shared state when the lock is held.
68
+ let mut data = data. lock ( ) ;
69
+ * data += 1 ;
70
+ if * data == N {
71
+ tx. send ( ( ) ) . unwrap ( ) ;
72
+ }
73
+ // the lock is unlocked here when `data` goes out of scope.
74
+ } ) ;
75
+ }
76
+
77
+ rx. recv ( ) . unwrap ( ) ;
78
+
79
+ println ! ( "fairmutex_example: done" ) ;
80
+ }
81
+
82
+ pub fn rwmutex_example ( ) {
83
+ const N : usize = 10 ;
84
+
85
+ let lock = Arc :: new ( RwLock :: new ( 5 ) ) ;
86
+
87
+ let handles: Vec < _ > = ( 0 ..N )
88
+ . map ( |i| {
89
+ let lock = Arc :: clone ( & lock) ;
90
+ thread:: spawn ( move || {
91
+ if i % 2 == 0 {
92
+ let mut num = lock. write ( ) ;
93
+ * num += 1 ;
94
+ } else {
95
+ let num = lock. read ( ) ;
96
+ println ! ( "thread {} read {}" , i, num) ;
97
+ }
98
+ } )
99
+ } )
100
+ . collect ( ) ;
101
+
102
+ for handle in handles {
103
+ handle. join ( ) . unwrap ( ) ;
104
+ }
105
+
106
+ println ! ( "rwmutex_example: {}" , lock. read( ) ) ;
107
+ }
108
+ pub fn reentrantmutex_example ( ) {
109
+ let lock = ReentrantMutex :: new ( ( ) ) ;
110
+
111
+ reentrant ( & lock, 10 ) ;
112
+
113
+ println ! ( "reentrantMutex_example: done" ) ;
114
+ }
115
+
116
+ fn reentrant ( lock : & ReentrantMutex < ( ) > , i : usize ) {
117
+ if i == 0 {
118
+ return ;
119
+ }
120
+
121
+ let _lock = lock. lock ( ) ;
122
+ reentrant ( lock, i - 1 ) ;
123
+ }
124
+
125
+ pub fn once_example ( ) {
126
+ static mut VAL : usize = 0 ;
127
+ static INIT : Once = Once :: new ( ) ;
128
+ fn get_cached_val ( ) -> usize {
129
+ unsafe {
130
+ INIT . call_once ( || {
131
+ println ! ( "initializing once" ) ;
132
+ thread:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) ;
133
+ VAL = 100 ;
134
+ } ) ;
135
+ VAL
136
+ }
137
+ }
138
+
139
+
140
+ let handle = thread:: spawn ( || {
141
+ println ! ( "thread 1 get_cached_val: {}" , get_cached_val( ) ) ;
142
+ } ) ;
143
+
144
+ println ! ( "get_cached_val: {}" , get_cached_val( ) ) ;
145
+
146
+ handle. join ( ) . unwrap ( ) ;
147
+ }
148
+
149
+
150
+ pub fn condvar_example ( ) {
151
+ use std:: sync:: Condvar ;
152
+ use std:: sync:: Mutex ;
153
+
154
+ let pair = Arc :: new ( ( Mutex :: new ( false ) , Condvar :: new ( ) ) ) ;
155
+ let pair2 = Arc :: clone ( & pair) ;
156
+
157
+ thread:: spawn ( move || {
158
+ let ( lock, cvar) = & * pair2;
159
+ let mut started = lock. lock ( ) . unwrap ( ) ;
160
+ * started = true ;
161
+ cvar. notify_one ( ) ;
162
+ } ) ;
163
+
164
+ let ( lock, cvar) = & * pair;
165
+ let mut started = lock. lock ( ) . unwrap ( ) ;
166
+ while !* started {
167
+ started = cvar. wait ( started) . unwrap ( ) ; // block until notified
168
+ }
169
+ println ! ( "condvar_example: done" ) ;
170
+ }
0 commit comments