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