|
1 | | -# synchronized |
2 | | -[](https://github.com/clucompany/synchronized/actions/workflows/CI.yml) |
3 | | -[](./LICENSE) |
4 | | -[](https://crates.io/crates/synchronized) |
5 | | -[](https://docs.rs/synchronized) |
| 1 | +<div id="header" align="center"> |
| 2 | + |
| 3 | + <b>[synchronized]</b> |
| 4 | + |
| 5 | + (Simple and convenient macro for synchronizing code in multithreading. ) |
| 6 | + </br></br> |
| 7 | + |
| 8 | +<div id="badges"> |
| 9 | + <a href="./LICENSE_APACHE"> |
| 10 | + <img src="https://github.com/UlinProject/img/blob/main/short_32/apache2.png?raw=true" alt="apache2"/> |
| 11 | + </a> |
| 12 | + <a href="https://crates.io/crates/synchronized"> |
| 13 | + <img src="https://github.com/UlinProject/img/blob/main/short_32/cratesio.png?raw=true" alt="cratesio"/> |
| 14 | + </a> |
| 15 | + <a href="https://docs.rs/synchronized"> |
| 16 | + <img src="https://github.com/UlinProject/img/blob/main/short_32/docrs.png?raw=true" alt="docrs"/> |
| 17 | + </a> |
| 18 | + <a href="https://github.com/denisandroid"> |
| 19 | + <img src="https://github.com/UlinProject/img/blob/main/short_32/uproject.png?raw=true" alt="uproject"/> |
| 20 | + </a> |
| 21 | + <a href="https://github.com/clucompany"> |
| 22 | + <img src="https://github.com/UlinProject/img/blob/main/short_32/clulab.png?raw=true" alt="clulab"/> |
| 23 | + </a> |
| 24 | + |
| 25 | + [](https://github.com/clucompany/synchronized/actions/workflows/CI.yml) |
6 | 26 |
|
7 | | -Convenient and simple macro for code synchronization in multithreading. |
8 | 27 |
|
9 | | -# Use |
| 28 | +</div> |
| 29 | +</div> |
10 | 30 |
|
11 | | -### 1. easy/sync |
12 | 31 |
|
13 | | -```rust |
14 | | -use synchronized::sync; |
| 32 | +## Usage |
15 | 33 |
|
16 | | -/* |
17 | | - Quick implementation examples of blocking anonymous code. |
18 | | -*/ |
| 34 | +Add this to your Cargo.toml: |
19 | 35 |
|
20 | | -fn main() { |
21 | | - // #1 Anonymous inter-threaded synchronized code, |
22 | | - // in the case of multi-threading, one thread will wait for the completion of another. |
23 | | - sync! { |
24 | | - println!("1"); |
25 | | - } |
26 | | - |
27 | | - // #2 Anonymous inter-threaded synchronized code, |
28 | | - // in the case of multi-threading, one thread will wait for the completion of another. |
29 | | - sync!( println!("1"); ); |
30 | | -} |
| 36 | +```toml |
| 37 | +[dependencies] |
| 38 | +synchronized = "1.1.0" |
31 | 39 | ``` |
32 | 40 |
|
33 | | -### 2. sync_static |
| 41 | +and this to your source code: |
| 42 | + |
| 43 | +```rust |
| 44 | +use synchronized::sync; |
| 45 | +``` |
| 46 | + |
| 47 | +## Example |
| 48 | + |
| 49 | +### 1. sync_static |
34 | 50 |
|
35 | 51 | ```rust |
36 | 52 | use std::thread::spawn; |
@@ -89,6 +105,68 @@ fn sync_fn() -> usize { |
89 | 105 | } |
90 | 106 | ``` |
91 | 107 |
|
| 108 | +### 2. point |
| 109 | + |
| 110 | +```rust |
| 111 | +/* |
| 112 | + An example implementation of synchronized code with |
| 113 | + one non-anonymous synchronization point. |
| 114 | + |
| 115 | + This example creates a set of anonymous sync codes associated with a |
| 116 | + single named sync point. Each synchronization code executes in the same |
| 117 | + way as ordinary anonymous code, but execution occurs simultaneously in a |
| 118 | + multi-threaded environment in only one of them. |
| 119 | + |
| 120 | + !!! In this example, the assembly requires the `point` feature to be active. |
| 121 | +*/ |
| 122 | + |
| 123 | +use synchronized::sync_point; |
| 124 | +use synchronized::sync; |
| 125 | + |
| 126 | +fn main() { |
| 127 | + // A sync point named `COMB_SYNC` to group anonymous code syncs by name. |
| 128 | + sync_point! {(COMB_SYNC) { |
| 129 | + static mut POINT: usize = 0; |
| 130 | + println!("GeneralSyncPoint, name_point: {}", COMB_SYNC.get_sync_point_name()); |
| 131 | + |
| 132 | + // #1 Anonymous synchronized code that operates on a |
| 133 | + // single named synchronization point. |
| 134 | + // |
| 135 | + // This code is not executed concurrently in a multi-threaded environment, |
| 136 | + // one thread is waiting for someone else's code to execute in this part of the code. |
| 137 | + let result0 = sync! ((->COMB_SYNC) { |
| 138 | + println!("SyncCode, name_point: {}", COMB_SYNC.get_sync_point_name()); |
| 139 | + unsafe { |
| 140 | + POINT += 1; |
| 141 | + |
| 142 | + POINT |
| 143 | + } |
| 144 | + }); |
| 145 | + |
| 146 | + // This line of code is not synchronized and can run concurrently on all threads. |
| 147 | + println!("Unsynchronized code"); |
| 148 | + |
| 149 | + // #2 Anonymous synchronized code that operates on a |
| 150 | + // single named synchronization point. |
| 151 | + // |
| 152 | + // Note that `result0` and `result1` cannot be calculated at the same time, |
| 153 | + // this does not happen because `result0` or `result1` are calculated in |
| 154 | + // synchronized code with a single sync point of the same name. |
| 155 | + let result1 = sync! ((->COMB_SYNC) { |
| 156 | + println!("SyncCode, name_point: {}", COMB_SYNC.get_sync_point_name()); |
| 157 | + unsafe { |
| 158 | + POINT += 1; |
| 159 | + |
| 160 | + POINT |
| 161 | + } |
| 162 | + }); |
| 163 | + |
| 164 | + // Display debug information. |
| 165 | + println!("result, res0: {:?}, res1: {:?}", result0, result1); |
| 166 | + }} |
| 167 | +} |
| 168 | +``` |
| 169 | + |
92 | 170 | ### 3. sync_let |
93 | 171 |
|
94 | 172 | ```rust |
@@ -152,122 +230,72 @@ fn main() { |
152 | 230 | } |
153 | 231 | ``` |
154 | 232 |
|
155 | | -### 4. point |
| 233 | +<a href="./examples"> |
| 234 | + See all |
| 235 | +</a> |
156 | 236 |
|
157 | | -```rust |
158 | | -/* |
159 | | - An example implementation of synchronized code with |
160 | | - one non-anonymous synchronization point. |
161 | | - |
162 | | - This example creates a set of anonymous sync codes associated with a |
163 | | - single named sync point. Each synchronization code executes in the same |
164 | | - way as ordinary anonymous code, but execution occurs simultaneously in a |
165 | | - multi-threaded environment in only one of them. |
166 | | - |
167 | | - !!! In this example, the assembly requires the `point` feature to be active. |
168 | | -*/ |
169 | 237 |
|
170 | | -use synchronized::sync_point; |
171 | | -use synchronized::sync; |
| 238 | +# Features |
172 | 239 |
|
173 | | -fn main() { |
174 | | - // A sync point named `COMB_SYNC` to group anonymous code syncs by name. |
175 | | - sync_point! {(COMB_SYNC) { |
176 | | - static mut POINT: usize = 0; |
177 | | - println!("GeneralSyncPoint, name_point: {}", COMB_SYNC.get_sync_point_name()); |
178 | | - |
179 | | - // #1 Anonymous synchronized code that operates on a |
180 | | - // single named synchronization point. |
181 | | - // |
182 | | - // This code is not executed concurrently in a multi-threaded environment, |
183 | | - // one thread is waiting for someone else's code to execute in this part of the code. |
184 | | - let result0 = sync! ((->COMB_SYNC) { |
185 | | - println!("SyncCode, name_point: {}", COMB_SYNC.get_sync_point_name()); |
186 | | - unsafe { |
187 | | - POINT += 1; |
188 | | - |
189 | | - POINT |
190 | | - } |
191 | | - }); |
192 | | - |
193 | | - // This line of code is not synchronized and can run concurrently on all threads. |
194 | | - println!("Unsynchronized code"); |
195 | | - |
196 | | - // #2 Anonymous synchronized code that operates on a |
197 | | - // single named synchronization point. |
198 | | - // |
199 | | - // Note that `result0` and `result1` cannot be calculated at the same time, |
200 | | - // this does not happen because `result0` or `result1` are calculated in |
201 | | - // synchronized code with a single sync point of the same name. |
202 | | - let result1 = sync! ((->COMB_SYNC) { |
203 | | - println!("SyncCode, name_point: {}", COMB_SYNC.get_sync_point_name()); |
204 | | - unsafe { |
205 | | - POINT += 1; |
206 | | - |
207 | | - POINT |
208 | | - } |
209 | | - }); |
210 | | - |
211 | | - // Display debug information. |
212 | | - println!("result, res0: {:?}, res1: {:?}", result0, result1); |
213 | | - }} |
214 | | -} |
215 | | -``` |
216 | | - |
217 | | -# Connection |
218 | | - |
219 | | -This section only describes how to choose the default synchronization method for a `synchronized` macro. |
| 240 | +Synchronized supports locks from the standard `std` package, as well as the `parking_lot` package, and also supports asynchronous operation using locks from `tokio`: |
220 | 241 |
|
221 | | -### 1. PlugAndPlay (minimal, sync, std) |
222 | | - |
223 | | -For a `synchronized` macro, use the primitives implemented by the default `std` library. |
| 242 | +### 1. `std` (only synchronization locks from the `std` library) |
224 | 243 |
|
225 | 244 | ```rust,ignore |
226 | 245 | [dependencies.synchronized] |
227 | | -version = "1.0.4" |
| 246 | +version = "1.1.0" |
228 | 247 | default-features = false |
229 | 248 | features = [ |
230 | 249 | "std", |
231 | | - #"point", |
| 250 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
232 | 251 | ] |
233 | 252 | ``` |
234 | 253 |
|
235 | | -### 2. PlugAndPlay (minimal, sync, parking_lot) |
236 | | - |
237 | | -For a `synchronized` macro, use the primitives implemented by the default `parking_lot` library. |
| 254 | +### 2. `parking_lot` (only synchronization locks from the `parking_lot` library) |
238 | 255 |
|
239 | 256 | ```rust,ignore |
240 | 257 | [dependencies.synchronized] |
241 | 258 | version = "1.1.0" |
242 | 259 | default-features = false |
243 | 260 | features = [ |
244 | 261 | "pl", |
245 | | - #"point", |
| 262 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
246 | 263 | ] |
247 | 264 | ``` |
248 | 265 |
|
249 | | -### 3. PlugAndPlay (minimal, async, tokio+parking_lot+async_trait) |
250 | | - |
251 | | -For a `synchronized` macro, use the primitives implemented by the default `tokio` library. |
| 266 | +### 3. `tokio` (only async locks from `tokio` library) |
252 | 267 |
|
253 | 268 | ```rust,ignore |
254 | 269 | [dependencies.synchronized] |
255 | 270 | version = "1.1.0" |
256 | 271 | default-features = false |
257 | 272 | features = [ |
258 | 273 | "async", |
259 | | - #"point", |
| 274 | + #"point", # Allows the use of synchronization points to avoid executing code in two or more places at the same time. |
260 | 275 | ] |
261 | 276 | ``` |
262 | 277 |
|
263 | | -# Additionally inf |
| 278 | +## License |
264 | 279 |
|
265 | | -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. |
| 280 | +This project is distributed under the license (LICENSE-APACHE-2-0). |
266 | 281 |
|
267 | | -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). |
268 | | - |
269 | | -# License |
270 | | - |
271 | | -Copyright 2022-2025 #UlinProject Denis Kotlyarov (Денис Котляров) |
272 | | - |
273 | | -Licensed under the Apache License, Version 2.0 |
| 282 | +<div align="left"> |
| 283 | + <a href="https://github.com/denisandroid"> |
| 284 | + <img align="left" src="https://github.com/UlinProject/img/blob/main/block_220_100/uproject.png?raw=true" alt="uproject"/> |
| 285 | + </a> |
| 286 | + <b> Copyright (c) 2022-2025 #UlinProject</b> |
| 287 | + |
| 288 | + <b> (Denis Kotlyarov).</b> |
| 289 | + </br></br></br> |
| 290 | +</div> |
| 291 | + |
| 292 | +### Apache License |
| 293 | + |
| 294 | +<div align="left"> |
| 295 | + <a href="./LICENSE_APACHE"> |
| 296 | + <img align="left" src="https://github.com/UlinProject/img/blob/main/block_220_100/apache2.png?raw=true" alt="apache2"/> |
| 297 | + |
| 298 | + </a> |
| 299 | + <b> Licensed under the Apache License, Version 2.0.</b> |
| 300 | + </br></br></br></br> |
| 301 | +</div> |
0 commit comments