{"id":34109275,"url":"https://github.com/mnpatil17/threading-tools","last_synced_at":"2026-04-06T06:32:53.226Z","repository":{"id":57475250,"uuid":"94027878","full_name":"mnpatil17/threading-tools","owner":"mnpatil17","description":"Datastructures and decorators for threading in Python","archived":false,"fork":false,"pushed_at":"2021-02-05T05:57:58.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-28T05:28:04.321Z","etag":null,"topics":["atomic","datastructures","datatypes","decorators","python","synchronized","threading"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mnpatil17.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-11T19:46:19.000Z","updated_at":"2021-02-05T05:58:00.000Z","dependencies_parsed_at":"2022-09-07T17:12:51.343Z","dependency_job_id":null,"html_url":"https://github.com/mnpatil17/threading-tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mnpatil17/threading-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnpatil17%2Fthreading-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnpatil17%2Fthreading-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnpatil17%2Fthreading-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnpatil17%2Fthreading-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mnpatil17","download_url":"https://codeload.github.com/mnpatil17/threading-tools/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mnpatil17%2Fthreading-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31463014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["atomic","datastructures","datatypes","decorators","python","synchronized","threading"],"created_at":"2025-12-14T18:29:25.439Z","updated_at":"2026-04-06T06:32:53.221Z","avatar_url":"https://github.com/mnpatil17.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Threading Tools\n[![Build Status](https://travis-ci.org/mnpatil17/threading-tools.svg?branch=master)](https://travis-ci.org/mnpatil17/threading-tools)\n[![Latest Version](https://img.shields.io/pypi/v/threading-tools.svg)](https://pypi.python.org/pypi/threading-tools/)\n\n\n## Installation\n\nThis package uses pip for installation. You can find out more information about pip [here](https://pip.pypa.io/en/stable/quickstart/).\n\nInstallation can be done directly through pip, using `pip install threading-tools`.\n\nIf this doesn't work, or you prefer having the source code on your machine, you can also execute the\nfollowing:\n\n1. `git clone https://github.com/mnpatil17/threading-tools.git`\n2. `cd threading_tools`\n3. `pip install -e .`\n\n## Usage\n\n### Function Decorator `@threaded_fn`\nJust decorate a function of your choice with `@threaded_fn`, and it will run on a separate thread. Additionally, `threaded_fn` returns the `threading.Thread` object that represents the thread that is running your function.\n\n    \u003e\u003e\u003e from threading_tools import threaded_fn\n    \u003e\u003e\u003e @threaded_fn\n    ... def your_function(arg0, arg1, kwarg0=None, kwarg1=None):\n    ...     # your logic here...\n    ...\n    \u003e\u003e\u003e new_thread = your_function(5, 10, kwarg0=15, kwarg1=20)  # The function is now executing on new_thread\n\nNote: this implementation was inspired by [freakish on StackOverflow](https://stackoverflow.com/questions/19846332/python-threading-inside-a-class?answertab=active#tab-top).\n\n### `SynchronizedNumber`\nThe `SynchronizedNumber` object is a threadsafe number that can be incremented and decremented atomically. Incrementation and decrementation can also be done only after a user-specified condition is passed. Here are a list of available methods for the class.\n\n##### Math Operators\nBasic mathematical operators such as `+`, `-`, `/`, `*`, `**`, `%` all work as expected for `SynchronizedNumber` objects. Note that **these operators return new `SynchronizedNumber`objects; they do not mutate the original(s)**. Here is an example.\n \n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e new_sync_num = sync_number + 5.0  # Returns a new SynchronizedNumber object with value 20.0\n    \u003e\u003e\u003e new_sync_num\n    20.0\n    \u003e\u003e\u003e sync_number  # Original SynchronizedNumber was NOT modified\n    15.0\n\nThese operations are not particularly useful in a multithreading context, but exist for the completeness of the datastructure itself.\n\n##### Augmented Assignment Operators\nAugmented Assignment operators such as `+=`, `-=`, `/=`, `*=` also work as expected for `SynchronizedNumber` and are threadsafe, atomic operations. These operations **change the value of the existing `SynchronizedNumber`**; they do not create a new object. Here is an example.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number += 5.0\n    \u003e\u003e\u003e sync_number  # Original SynchronizedNumber WAS modified in a threadsafe manner\n    20.0\n\n##### `increment(self, incr_value)`\nThe `increment` method simply increments the value of the `SynchronizedNumber` by `incr_value`. Returns whether incrementation was successful or not. This behavior is very similar to the `+=` Augmented Assignment operator, except for the fact that this method returns success or failure.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.increment(10.0)\n    True\n    \u003e\u003e\u003e sync_number\n    25.0\n\n##### `decrement(self, decr_value)`\nThe `decrement` method simply decrements the value of the `SynchronizedNumber` by `decr_value`. Returns whether incrementation was successful or not. This behavior is very similar to the `-=` Augmented Assignment operator, except for the fact that this method returns success or failure.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.decrement(10.0)\n    True\n    \u003e\u003e\u003e sync_number\n    5.0\n\n##### `increment_if_less_than(self, incr_value, limit, eq_ok=False)`\nThe `increment_if_less_than` method increments the value of the `SynchronizedNumber` by `incr_value` if the value of the `SynchronizedNumber` is less than `limit`, or if `eq_ok` is `True`and the `SynchronizedNumber`'s value is equal to `limit`.\n\nHere's an example where incrementation fails because the limit is reached.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.increment_if_less_than(10.0, 15.0)\n    False\n    \u003e\u003e\u003e sync_number\n    15.0\n\nHere's an example where incrementation succeeds because the limit is not reached.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.increment_if_less_than(10.0, 15.0, eq_ok=True)\n    True\n    \u003e\u003e\u003e sync_number\n    25.0\n\n##### `decrement_if_greater_than(self, decr_value, limit, eq_ok=False)`\nThe `decrement_if_greater_than` method decrements the value of the `SynchronizedNumber` by `decr_value` if the value of the `SynchronizedNumber` is greater than `limit`, or if `eq_ok` is `True`and the `SynchronizedNumber`'s value is equal to `limit`.\n\nHere's an example where decrementation fails because the limit is reached.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.decrement_if_greater_than(10.0, 15.0)\n    False\n    \u003e\u003e\u003e sync_number\n    15.0\n\nHere's an example where incrementation succeeds because the limit is not reached.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e sync_number.decrement_if_greater_than(10.0, 15.0, eq_ok=True)\n    True\n    \u003e\u003e\u003e sync_number\n    5.0\n\n\n##### `increment_if_satisfies_condition(self, incr_value, satisfaction_condition)`\nThe `increment_if_satisfies_condition` method increments the value of the `SynchronizedNumber` by `incr_value` if the `satisfaction_condition` is met. `satisfaction_condition` is a method that takes in the value of the `SynchronizedNumber` and returns `True` or `False` based on conditions determined by the user.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e condition_func = lambda x: 10 \u003c x \u003c 20\n    \u003e\u003e\u003e sync_number.increment_if_satisfies_condition(10.0, condition_func)  # condition is satisfied, since 10 \u003c 15.0 \u003c 20 is True\n    True\n    \u003e\u003e\u003e sync_number\n    25.0\n    \u003e\u003e\u003e sync_number.increment_if_satisfies_condition(10.0, condition_func)  # condition is NOT satisfied, since 10 \u003c 25.0 \u003c 20 is False\n    False\n    \u003e\u003e\u003e sync_number\n    25.0\n\n##### `decrement_if_satisfies_condition(self, decr_value, satisfaction_condition)`\nThe `decrement_if_satisfies_condition` method decrements the value of the `SynchronizedNumber` by `decr_value` if the `satisfaction_condition` is met. `satisfaction_condition` is a method that takes in the value of the `SynchronizedNumber` and returns `True` or `False` based on conditions determined by the user.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e condition_func = lambda x: 10 \u003c x \u003c 20\n    \u003e\u003e\u003e sync_number.decrement_if_satisfies_condition(10.0, condition_func)  # condition is satisfied, since 10 \u003c 15.0 \u003c 20 is True\n    True\n    \u003e\u003e\u003e sync_number\n    5.0\n    \u003e\u003e\u003e sync_number.decrement_if_satisfies_condition(10.0, condition_func)  # condition is NOT satisfied, since 10 \u003c 25.0 \u003c 20 is False\n    False\n    \u003e\u003e\u003e sync_number\n    5.0\n\n##### `imultiply_if_satisfies_condition(self, mul_value, satisfaction_condition)`\nThe `imultiply_if_satisfies_condition` method increments the value of the `SynchronizedNumber` by `mul_value` if the `satisfaction_condition` is met. `satisfaction_condition` is a method that takes in the value of the `SynchronizedNumber` and returns `True` or `False` based on conditions determined by the user.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e condition_func = lambda x: 10 \u003c x \u003c 20\n    \u003e\u003e\u003e sync_number.imultiply_if_satisfies_condition(2.0, condition_func)  # condition is satisfied, since 10 \u003c 15.0 \u003c 20 is True\n    True\n    \u003e\u003e\u003e sync_number\n    30.0\n    \u003e\u003e\u003e sync_number.imultiply_if_satisfies_condition(2.0, condition_func)  # condition is NOT satisfied, since 10 \u003c 30.0 \u003c 20 is False\n    False\n    \u003e\u003e\u003e sync_number\n    30.0\n\n##### `idivide_if_satisfies_condition(self, div_value, satisfaction_condition)`\nThe `idivide_if_satisfies_condition` method increments the value of the `SynchronizedNumber` by `div_value` if the `satisfaction_condition` is met. `satisfaction_condition` is a method that takes in the value of the `SynchronizedNumber` and returns `True` or `False` based on conditions determined by the user.\n\n    \u003e\u003e\u003e from threading_tools import SynchronizedNumber\n    \u003e\u003e\u003e sync_number = SynchronizedNumber(15.0)\n    \u003e\u003e\u003e condition_func = lambda x: 10 \u003c x \u003c 20\n    \u003e\u003e\u003e sync_number.idivide_if_satisfies_condition(3.0, condition_func)  # condition is satisfied, since 10 \u003c 15.0 \u003c 20 is True\n    True\n    \u003e\u003e\u003e sync_number\n    5.0\n    \u003e\u003e\u003e sync_number.idivide_if_satisfies_condition(3.0, condition_func)  # condition is NOT satisfied, since 10 \u003c 5.0 \u003c 20 is False\n    False\n    \u003e\u003e\u003e sync_number\n    5.0\n\n\n## Testing\n\nIf you choose, you can clone this repository locally and run the tests yourself.\nTo run tests, simply run `nosetests` from the `threading_tools/` directory.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnpatil17%2Fthreading-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmnpatil17%2Fthreading-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmnpatil17%2Fthreading-tools/lists"}