Skip to main content

An easy to use variable sharing library for Python using Memcached to can quickly share complex objects between processes as if they had shared memory.

Project description

Introduction

EasyGlobals is an easy to use variable sharing library for Python that can quickly share almost all types of variables and full Python objects between processes as if they had shared memory.

It uses Memcached in the background to share full objects and other complex variables between Python processes. Inspired by many closed source languages which have an easy way to share "global" variables between processes while retaining pythonic syntax. No need for Multiprocessing Manager dicts, queues and other complex data pipelines in your program anymore.

Usage

After installation following the instructions down below, try running the following example

import EasyGlobals
globals = EasyGlobals.Globals()

globals.test1 = 4
globals.test2 = 'hello world'
globals.test3 = {'dictkey1': globals.test1, 'dictkey2': globals.test2} #  Dict

print(globals.test1)
print(globals.test2)
print(globals.test3)
  • Keep in mind that locks are not implemented here, meaning that race conditions can happen if two processes are writing to the same variable at the same time. For example when they're both incrementing the same value in a loop this can cause unwanted behavior.

  • To prevent this, an easy solution is to write to a variable in only one process. Reading can be done in as many processes as desired. Writing on multiple processes is not restricted but you will need to deal with the race conditions so prepare for coding headaches if you do.

Installation

Install Memcached which acts as the server. installation with Apt is availible on Ubuntu. Different operating systems haven't been tested yet but installation guides with Windows can be found online

sudo apt install memcached
sudo systemctl start memcached

Now you can install the easyglobals library:

pip install easyglobals

Limitations:

  • Any variable type that can be pickled should work. E.g. Numpy arrays, OpenCV images.
  • Directly getting and setting values from nested objects such as dicts or classes in the Globals can be problematic as the values are in binary format (pickled) while they are in memcached.
  • It's currently best to retrieve the an object from globals, modify it locally, and then store the entire object in globals again
  • If you're already using Memcached and your variable keys have the same name they will be overwritten
  • All variables will stay stored in Memcached even when your program stops. Restart memached to clear them, for example by running "service memcached restart" in the terminal.

Speed 🚀

Tested on a Ryzen 5900X

  • 100.000 writes/reads per second on for small variables

  • 1.000 writes/reads per second for big variables such as 4K OpenCV images.

  • This is around 200-400 times slower than using normal Python local variables. For most programs this won't matter but keep in mind that any variable in direct process memory will always be faster than having to pickle it and send it to Memcached.

  • Redis and SQLite have been tested as potential back-ends but were too slow.

  • Memcached was the fastest as it is a dedicated key-value DB.

  • Redis is more designed for distributed computing and storing a huge amount of variables.

  • SQLite cannot share variables between processes while running in-memory.

Multiprocessing example:

from EasyGlobals import EasyGlobals
import multiprocessing

def write_to_globals():
    g = EasyGlobals.Globals()
    for i in range(1_000):
        g.testvar = i

def retrieve_from_globals(process_id):
    g = EasyGlobals.Globals()
    for i in range(10):
        result = g.testvar
        print(f'Process {process_id}, read: {result}')


print('Start writing process')
write_process = multiprocessing.Process(target=write_to_globals)
write_process.start()

print('Start reading with 3 simultaneous processes')
processlist = []
for i in range(5):
    processlist.append(multiprocessing.Process(target=retrieve_from_globals, args=(i,)))
    processlist[i].start()

for process in processlist:
    process.join()
print('Done reading')
write_process.join()
print('Done writing')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

easyglobals-0.1.1.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

easyglobals-0.1.1-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file easyglobals-0.1.1.tar.gz.

File metadata

  • Download URL: easyglobals-0.1.1.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.0rc1

File hashes

Hashes for easyglobals-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4f42054627d6007d57f5f72f32a64721bcebcbd3b23113907c1911298526e1c0
MD5 983b04762d5a80d5b41143d9376cd706
BLAKE2b-256 83a1a1b7f42dda5bef3fce20f8dddada6c57c212478cb454636474fa8fea4729

See more details on using hashes here.

File details

Details for the file easyglobals-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: easyglobals-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.0rc1

File hashes

Hashes for easyglobals-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4cdef9bfeb196144312d4a64853a0e7c06cf2ee8fb9db4d4ea0e65e514800101
MD5 f4e21260f9e082610ab3b9eac1824e54
BLAKE2b-256 2224557746966b3edd4bfcb3f6506bb9bbbad0ba05948403d39ba55a61e30da7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page