{"id":21500262,"url":"https://github.com/clucompany/synchronized","last_synced_at":"2025-03-17T13:15:37.260Z","repository":{"id":56821629,"uuid":"496794775","full_name":"clucompany/synchronized","owner":"clucompany","description":"Convenient and simple macro for code synchronization in multithreading.","archived":false,"fork":false,"pushed_at":"2022-12-25T23:17:25.000Z","size":81,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-28T07:51:35.156Z","etag":null,"topics":["clucompany","easy-sync-code","no-std","synchronized","synchronized-point"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clucompany.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-05-26T22:53:32.000Z","updated_at":"2022-08-17T20:18:25.000Z","dependencies_parsed_at":"2023-01-30T22:45:17.781Z","dependency_job_id":null,"html_url":"https://github.com/clucompany/synchronized","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clucompany%2Fsynchronized","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clucompany%2Fsynchronized/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clucompany%2Fsynchronized/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clucompany%2Fsynchronized/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clucompany","download_url":"https://codeload.github.com/clucompany/synchronized/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244039241,"owners_count":20387835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clucompany","easy-sync-code","no-std","synchronized","synchronized-point"],"created_at":"2024-11-23T17:23:09.212Z","updated_at":"2025-03-17T13:15:37.229Z","avatar_url":"https://github.com/clucompany.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# synchronized\n[![CI](https://github.com/clucompany/synchronized/actions/workflows/CI.yml/badge.svg?event=push)](https://github.com/clucompany/synchronized/actions/workflows/CI.yml)\n[![Apache licensed](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](./LICENSE)\n[![crates.io](https://img.shields.io/crates/v/synchronized)](https://crates.io/crates/synchronized)\n[![Documentation](https://docs.rs/synchronized/badge.svg)](https://docs.rs/synchronized)\n\nConvenient and simple macro for code synchronization in multithreading.\n\n# Use\n\n### 1. easy/sync\n\n```rust\nuse synchronized::synchronized;\n\n/*\n\tQuick implementation examples of blocking anonymous code.\n*/\n\nfn main() {\n\t// #1 Anonymous inter-threaded synchronized code, \n\t// in the case of multi-threading, one thread will wait for the completion of another.\n\tsynchronized! {\n\t\tprintln!(\"1\");\n\t}\n\t\n\t// #2 Anonymous inter-threaded synchronized code, \n\t// in the case of multi-threading, one thread will wait for the completion of another.\n\tsynchronized!( println!(\"1\"); );\n}\n```\n\n### 2. sync_static\n\n```rust\nuse std::thread::spawn;\nuse synchronized::synchronized;\n\n/*\n\tA more illustrative example of code blocking implementation \n\tfor SAFE mutability of two or more static variables.\n\t\n\tThe code creates 5 threads that try to change static variables at the same \n\ttime without synchronization, but the code synchronization block \n\tdoes not allow this code to execute at the same time, which makes \n\tthe implementation of changing static variables SAFE and even somewhat \n\teasier and more beneficial in terms of use and performance.\n*/\n\nfn main() {\n\t// An array of handles to wait for all threads to complete.\n\tlet mut join_all = Vec::new();\n\t\n\t// Creation of 5 threads to implement a multi-threaded environment.\n\tfor thread_id in 0..5 {\n\t\tlet join = spawn(move || {\n\t\t\t// Print the thread number and print the \n\t\t\t// result of the sync_fn function.\n\t\t\tprintln!(\"#[id: {}] {}\", thread_id, sync_fn());\n\t\t});\n\t\t\n\t\tjoin_all.push(join);\n\t}\n\t\n\t// We just wait for all threads to finish and look at stdout.\n\tfor tjoin in join_all {\n\t\tlet _e = tjoin.join();\n\t}\n}\n\nfn sync_fn() -\u003e usize {\n\t// Create anonymous synchronized code.\n\t//\n\t// The code will never run at the same time. If one thread is executing \n\t// this code, the second thread will wait for this code to finish executing.\n\tlet result = synchronized! {\n\t\tstatic mut POINT0: usize = 0;\n\t\tstatic mut POINT1: usize = 0;\n\t\t\n\t\tunsafe {\n\t\t\tPOINT1 = POINT0;\n\t\t\tPOINT0 += 1;\n\t\t\t\n\t\t\tPOINT1\n\t\t}\n\t};\n\t\n\tresult\n}\n```\n\n### 3. sync_let\n\n```rust\nuse std::thread::spawn;\nuse synchronized::synchronized;\n\n/*\n\tAn example that describes how to quickly create an anonymous \n\tsync with a mutable variable.\n\t\n\tThis code creates 5 threads, each of which tries to update \n\tthe `sync_let` variable with data while executing the synchronized anonymous code.\n*/\n\nfn main() {\n\t// An array of handles to wait for all threads to complete.\n\tlet mut join_all = Vec::new();\n\t\n\t// Creation of 5 threads to implement a multi-threaded environment.\n\tfor thread_id in 0..5 {\n\t\tlet join = spawn(move || {\n\t\t\t// Create anonymous synchronized code with one mutable variable `sync_let` and `count`.\n\t\t\tlet result = synchronized!(\n\t\t\t\t(sync_let: String = String::new(), count: usize = 0) {\n\t\t\t\t\t// If it's the first thread, \n\t\t\t\t\t// then theoretically `sync_let` is String::new().\n\t\t\t\t\tif thread_id == 0 {\n\t\t\t\t\t\tassert_eq!(sync_let.is_empty(), true);\n\t\t\t\t\t\tassert_eq!(count, \u00260);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// We fill the variable `sync_let` and `count` with data.\n\t\t\t\t\tsync_let.push_str(\u0026thread_id.to_string());\n\t\t\t\t\tsync_let.push_str(\" \");\n\t\t\t\t\t\n\t\t\t\t\t*count += 1;\n\t\t\t\t\t\n\t\t\t\t\tsync_let.clone()\n\t\t\t\t}\n\t\t\t);\n\t\t\t\n\t\t\t// Outputting debug information.\n\t\t\tprintln!(\"#[id: {}] {}\", thread_id, result);\n\t\t});\n\t\t\n\t\t// In order for our `assert_eq!(sync_let.is_empty());` code to \n\t\t// always run correctly, the first thread should always run first \n\t\t// (this is just for the stability of this example).\n\t\tif thread_id == 0 {\n\t\t\tlet _e = join.join();\n\t\t\tcontinue;\n\t\t}\n\t\t\n\t\tjoin_all.push(join);\n\t}\n\t\n\t// We just wait for all threads to finish and look at stdout.\n\tfor tjoin in join_all {\n\t\tlet _e = tjoin.join();\n\t}\n}\n```\n\n### 4. point\n\n```rust\n/*\n\tAn example implementation of synchronized code with \n\tone non-anonymous synchronization point.\n\t\n\tThis example creates a set of anonymous sync codes associated with a \n\tsingle named sync point. Each synchronization code executes in the same \n\tway as ordinary anonymous code, but execution occurs simultaneously in a \n\tmulti-threaded environment in only one of them.\n\t\n\t!!! In this example, the assembly requires the `point` feature to be active.\n*/\n\n#[cfg( feature = \"point\" )]\nuse synchronized::synchronized_point;\n#[cfg( feature = \"point\" )]\nuse synchronized::synchronized;\n\n#[cfg( not(feature = \"point\") )]\nmacro_rules! synchronized_point {\n\t[ $($unk:tt)* ] =\u003e {\n\t\tprintln!(\"!!! This example requires support for the `point` feature. Run the example with `cargo run --example point --all-features`.\");\n\t};\n}\n\nfn main() {\n\t// A sync point named `COMB_SYNC` to group anonymous code syncs by name.\n\tsynchronized_point! {(COMB_SYNC) {\n\t\tstatic mut POINT: usize = 0;\n\t\tprintln!(\"GeneralSyncPoint, name_point: {}\", COMB_SYNC.get_sync_point_name());\n\t\t\n\t\t// #1 Anonymous synchronized code that operates on a \n\t\t// single named synchronization point.\n\t\t//\n\t\t// This code is not executed concurrently in a multi-threaded environment, \n\t\t// one thread is waiting for someone else's code to execute in this part of the code.\n\t\tlet result0 = synchronized! ((-\u003eCOMB_SYNC) {\n\t\t\tprintln!(\"SyncCode, name_point: {}\", COMB_SYNC.get_sync_point_name());\n\t\t\tunsafe {\n\t\t\t\tPOINT += 1;\n\t\t\t\t\n\t\t\t\tPOINT\n\t\t\t}\n\t\t});\n\t\t\n\t\t// This line of code is not synchronized and can run concurrently on all threads.\n\t\tprintln!(\"Unsynchronized code\");\n\t\t\n\t\t// #2 Anonymous synchronized code that operates on a \n\t\t// single named synchronization point.\n\t\t//\n\t\t// Note that `result0` and `result1` cannot be calculated at the same time, \n\t\t// this does not happen because `result0` or `result1` are calculated in \n\t\t// synchronized code with a single sync point of the same name.\n\t\tlet result1 = synchronized! ((-\u003eCOMB_SYNC) {\n\t\t\tprintln!(\"SyncCode, name_point: {}\", COMB_SYNC.get_sync_point_name());\n\t\t\tunsafe {\n\t\t\t\tPOINT += 1;\n\t\t\t\t\n\t\t\t\tPOINT\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Display debug information.\n\t\tprintln!(\"result, res0: {:?}, res1: {:?}\", result0, result1);\n\t}}\n}\n```\n\n# Connection\n\nThis section only describes how to choose the default synchronization method for a `synchronized` macro.\n\n### 1. PlugAndPlay (minimal, sync, std)\n\nFor a `synchronized` macro, use the primitives implemented by the default `std` library.\n\n```rust,ignore\n[dependencies.synchronized]\nversion = \"1.0.4\"\ndefault-features = false\nfeatures = [\n\t\"std\",\n\t#\"point\",\n\t#\"get_point_name\"\n]\n```\n\n### 2. PlugAndPlay (minimal, sync, parking_lot)\n\nFor a `synchronized` macro, use the primitives implemented by the default `parking_lot` library.\n\n```rust,ignore\n[dependencies.synchronized]\nversion = \"1.0.4\"\ndefault-features = false\nfeatures = [\n\t\"parking_lot\",\n\t#\"point\",\n\t#\"get_point_name\"\n]\n```\n\n### 3. PlugAndPlay (minimal, async, tokio+parking_lot+async_trait)\n\nFor a `synchronized` macro, use the primitives implemented by the default `tokio` library.\n\n```rust,ignore\n[dependencies.synchronized]\nversion = \"1.0.4\"\ndefault-features = false\nfeatures = [\n\t\"async\",\n\t#\"point\",\n\t#\"get_point_name\"\n]\n```\n\n# Additionally inf\n\n1. The macro is an alternative to the `synchronized` keyword from the Java programming language for the Rust programming language with all sorts of extensions.\n\n2. 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).\n\n# License\n\nCopyright 2022 #UlinProject Denis Kotlyarov (Денис Котляров)\n\nLicensed under the Apache License, Version 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclucompany%2Fsynchronized","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclucompany%2Fsynchronized","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclucompany%2Fsynchronized/lists"}