|
17 | 17 |
|
18 | 18 | /*! |
19 | 19 |
|
20 | | -Convenient and simple macro for code synchronization in multithreading. |
| 20 | +Simple and convenient macro for synchronizing code in multithreading. |
21 | 21 |
|
22 | | -# Use |
| 22 | +# Usage |
23 | 23 |
|
24 | | -### 1. easy/sync |
25 | | -
|
26 | | -```rust |
27 | | -use synchronized::sync; |
28 | | -
|
29 | | -/* |
30 | | - Quick implementation examples of blocking anonymous code. |
31 | | -*/ |
32 | | -
|
33 | | -fn main() { |
34 | | - // #1 Anonymous inter-threaded synchronized code, |
35 | | - // in the case of multi-threading, one thread will wait for the completion of another. |
36 | | - sync! { |
37 | | - println!("1"); |
38 | | - } |
39 | | -
|
40 | | - // #2 Anonymous inter-threaded synchronized code, |
41 | | - // in the case of multi-threading, one thread will wait for the completion of another. |
42 | | - sync!( println!("1"); ); |
43 | | -} |
44 | | -``` |
45 | | -
|
46 | | -### 2. sync_static |
| 24 | +### 1. sync_static |
47 | 25 |
|
48 | 26 | ```rust |
49 | 27 | use std::thread::spawn; |
@@ -102,70 +80,8 @@ fn sync_fn() -> usize { |
102 | 80 | } |
103 | 81 | ``` |
104 | 82 |
|
105 | | -### 3. sync_let |
106 | | -
|
107 | | -```rust |
108 | | -use std::thread::spawn; |
109 | | -use synchronized::sync; |
110 | | -
|
111 | | -/* |
112 | | - An example that describes how to quickly create an anonymous |
113 | | - sync with a mutable variable. |
114 | | -
|
115 | | - This code creates 5 threads, each of which tries to update |
116 | | - the `sync_let` variable with data while executing the synchronized anonymous code. |
117 | | -*/ |
118 | | -
|
119 | | -fn main() { |
120 | | - // An array of handles to wait for all threads to complete. |
121 | | - let mut join_all = Vec::new(); |
122 | | -
|
123 | | - // Creation of 5 threads to implement a multi-threaded environment. |
124 | | - for thread_id in 0..5 { |
125 | | - let join = spawn(move || { |
126 | | - // Create anonymous synchronized code with one mutable variable `sync_let` and `count`. |
127 | | - let result = sync!( |
128 | | - (sync_let: String = String::new(), count: usize = 0) { |
129 | | - // If it's the first thread, |
130 | | - // then theoretically `sync_let` is String::new(). |
131 | | - if thread_id == 0 { |
132 | | - assert_eq!(sync_let.is_empty(), true); |
133 | | - assert_eq!(count, &0); |
134 | | - } |
135 | | -
|
136 | | - // We fill the variable `sync_let` and `count` with data. |
137 | | - sync_let.push_str(&thread_id.to_string()); |
138 | | - sync_let.push_str(" "); |
139 | | -
|
140 | | - *count += 1; |
141 | | -
|
142 | | - sync_let.clone() |
143 | | - } |
144 | | - ); |
145 | | -
|
146 | | - // Outputting debug information. |
147 | | - println!("#[id: {}] {}", thread_id, result); |
148 | | - }); |
149 | | -
|
150 | | - // In order for our `assert_eq!(sync_let.is_empty());` code to |
151 | | - // always run correctly, the first thread should always run first |
152 | | - // (this is just for the stability of this example). |
153 | | - if thread_id == 0 { |
154 | | - let _e = join.join(); |
155 | | - continue; |
156 | | - } |
157 | 83 |
|
158 | | - join_all.push(join); |
159 | | - } |
160 | | -
|
161 | | - // We just wait for all threads to finish and look at stdout. |
162 | | - for tjoin in join_all { |
163 | | - let _e = tjoin.join(); |
164 | | - } |
165 | | -} |
166 | | -``` |
167 | | -
|
168 | | -### 4. point |
| 84 | +### 2. point |
169 | 85 |
|
170 | 86 | ```rust |
171 | 87 | /* |
@@ -233,58 +149,108 @@ fn main() { |
233 | 149 | } |
234 | 150 | ``` |
235 | 151 |
|
236 | | -# Connection |
| 152 | +### 3. sync_let |
| 153 | +
|
| 154 | +```rust |
| 155 | +use std::thread::spawn; |
| 156 | +use synchronized::sync; |
| 157 | +
|
| 158 | +/* |
| 159 | + An example that describes how to quickly create an anonymous |
| 160 | + sync with a mutable variable. |
| 161 | +
|
| 162 | + This code creates 5 threads, each of which tries to update |
| 163 | + the `sync_let` variable with data while executing the synchronized anonymous code. |
| 164 | +*/ |
| 165 | +
|
| 166 | +fn main() { |
| 167 | + // An array of handles to wait for all threads to complete. |
| 168 | + let mut join_all = Vec::new(); |
237 | 169 |
|
238 | | -This section only describes how to choose the default synchronization method for a `synchronized` macro. |
| 170 | + // Creation of 5 threads to implement a multi-threaded environment. |
| 171 | + for thread_id in 0..5 { |
| 172 | + let join = spawn(move || { |
| 173 | + // Create anonymous synchronized code with one mutable variable `sync_let` and `count`. |
| 174 | + let result = sync!( |
| 175 | + (sync_let: String = String::new(), count: usize = 0) { |
| 176 | + // If it's the first thread, |
| 177 | + // then theoretically `sync_let` is String::new(). |
| 178 | + if thread_id == 0 { |
| 179 | + assert_eq!(sync_let.is_empty(), true); |
| 180 | + assert_eq!(count, &0); |
| 181 | + } |
239 | 182 |
|
240 | | -### 1. PlugAndPlay (minimal, sync, std) |
| 183 | + // We fill the variable `sync_let` and `count` with data. |
| 184 | + sync_let.push_str(&thread_id.to_string()); |
| 185 | + sync_let.push_str(" "); |
241 | 186 |
|
242 | | -For a `synchronized` macro, use the primitives implemented by the default `std` library. |
| 187 | + *count += 1; |
| 188 | +
|
| 189 | + sync_let.clone() |
| 190 | + } |
| 191 | + ); |
| 192 | +
|
| 193 | + // Outputting debug information. |
| 194 | + println!("#[id: {}] {}", thread_id, result); |
| 195 | + }); |
| 196 | +
|
| 197 | + // In order for our `assert_eq!(sync_let.is_empty());` code to |
| 198 | + // always run correctly, the first thread should always run first |
| 199 | + // (this is just for the stability of this example). |
| 200 | + if thread_id == 0 { |
| 201 | + let _e = join.join(); |
| 202 | + continue; |
| 203 | + } |
| 204 | +
|
| 205 | + join_all.push(join); |
| 206 | + } |
| 207 | +
|
| 208 | + // We just wait for all threads to finish and look at stdout. |
| 209 | + for tjoin in join_all { |
| 210 | + let _e = tjoin.join(); |
| 211 | + } |
| 212 | +} |
| 213 | +``` |
| 214 | +
|
| 215 | +## Features |
| 216 | +
|
| 217 | +Synchronized supports locks from the standard `std` package, as well as the `parking_lot` package, and also supports asynchronous operation using locks from `tokio`: |
| 218 | +
|
| 219 | +### 1. `std` (only synchronization locks from the `std` library) |
243 | 220 |
|
244 | 221 | ```rust,ignore |
245 | 222 | [dependencies.synchronized] |
246 | | -version = "1.0.4" |
| 223 | +version = "1.1.0" |
247 | 224 | default-features = false |
248 | 225 | features = [ |
249 | 226 | "std", |
250 | | - #"point" |
| 227 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
251 | 228 | ] |
252 | 229 | ``` |
253 | 230 |
|
254 | | -### 2. PlugAndPlay (minimal, sync, parking_lot) |
255 | | -
|
256 | | -For a `synchronized` macro, use the primitives implemented by the default `parking_lot` library. |
| 231 | +### 2. `parking_lot` (only synchronization locks from the `parking_lot` library) |
257 | 232 |
|
258 | 233 | ```rust,ignore |
259 | 234 | [dependencies.synchronized] |
260 | | -version = "1.0.4" |
| 235 | +version = "1.1.0" |
261 | 236 | default-features = false |
262 | 237 | features = [ |
263 | 238 | "pl", |
264 | | - #"point" |
| 239 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
265 | 240 | ] |
266 | 241 | ``` |
267 | 242 |
|
268 | | -### 3. PlugAndPlay (minimal, async, tokio+parking_lot+async_trait) |
269 | | -
|
270 | | -For a `synchronized` macro, use the primitives implemented by the default `tokio` library. |
| 243 | +### 3. `tokio` (only async locks from `tokio` library) |
271 | 244 |
|
272 | 245 | ```rust,ignore |
273 | 246 | [dependencies.synchronized] |
274 | | -version = "1.0.4" |
| 247 | +version = "1.1.0" |
275 | 248 | default-features = false |
276 | 249 | features = [ |
277 | 250 | "async", |
278 | | - #"point" |
| 251 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
279 | 252 | ] |
280 | 253 | ``` |
281 | | -
|
282 | | -# Additionally inf |
283 | | -
|
284 | | -1. The macro is an alternative to the `synchronized` keyword from the Java programming language for the Rust programming language with all sorts of extensions. |
285 | | -
|
286 | | -2. This macro was created by an author who has not written in Java for a very long time, inspired by the memory of the Java programming language (versions 1.5-1.6). |
287 | | -
|
288 | 254 | */ |
289 | 255 |
|
290 | 256 | #![allow(clippy::tabs_in_doc_comments)] |
|
0 commit comments